mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
almost yeeted it all!
This commit is contained in:
@ -20,9 +20,9 @@ const builtin = @import("builtin");
|
|||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
|
const global_state = &@import("global.zig").state;
|
||||||
const oni = @import("oniguruma");
|
const oni = @import("oniguruma");
|
||||||
const unicode = @import("unicode/main.zig");
|
const unicode = @import("unicode/main.zig");
|
||||||
const main = @import("main.zig");
|
|
||||||
const renderer = @import("renderer.zig");
|
const renderer = @import("renderer.zig");
|
||||||
const termio = @import("termio.zig");
|
const termio = @import("termio.zig");
|
||||||
const objc = @import("objc");
|
const objc = @import("objc");
|
||||||
@ -448,7 +448,7 @@ pub fn init(
|
|||||||
.shell_integration = config.@"shell-integration",
|
.shell_integration = config.@"shell-integration",
|
||||||
.shell_integration_features = config.@"shell-integration-features",
|
.shell_integration_features = config.@"shell-integration-features",
|
||||||
.working_directory = config.@"working-directory",
|
.working_directory = config.@"working-directory",
|
||||||
.resources_dir = main.state.resources_dir,
|
.resources_dir = global_state.resources_dir,
|
||||||
.term = config.term,
|
.term = config.term,
|
||||||
|
|
||||||
// Get the cgroup if we're on linux and have the decl. I'd love
|
// Get the cgroup if we're on linux and have the decl. I'd love
|
||||||
|
@ -5,7 +5,7 @@ const Action = @import("action.zig").Action;
|
|||||||
const Arena = std.heap.ArenaAllocator;
|
const Arena = std.heap.ArenaAllocator;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Config = @import("../config/Config.zig");
|
const Config = @import("../config/Config.zig");
|
||||||
const global_state = &@import("../main.zig").state;
|
const global_state = &@import("../global.zig").state;
|
||||||
|
|
||||||
pub const Options = struct {
|
pub const Options = struct {
|
||||||
pub fn deinit(self: Options) void {
|
pub fn deinit(self: Options) void {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const cli = @import("../cli.zig");
|
const cli = @import("../cli.zig");
|
||||||
const inputpkg = @import("../input.zig");
|
const inputpkg = @import("../input.zig");
|
||||||
const global = &@import("../main.zig").state;
|
const global = &@import("../global.zig").state;
|
||||||
|
|
||||||
const Config = @import("Config.zig");
|
const Config = @import("Config.zig");
|
||||||
const c_get = @import("c_get.zig");
|
const c_get = @import("c_get.zig");
|
||||||
|
@ -15,7 +15,7 @@ const builtin = @import("builtin");
|
|||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
const global_state = &@import("../main.zig").state;
|
const global_state = &@import("../global.zig").state;
|
||||||
const fontpkg = @import("../font/main.zig");
|
const fontpkg = @import("../font/main.zig");
|
||||||
const inputpkg = @import("../input.zig");
|
const inputpkg = @import("../input.zig");
|
||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
|
11
src/main.zig
11
src/main.zig
@ -1,7 +1,7 @@
|
|||||||
const build_config = @import("build_config.zig");
|
const build_config = @import("build_config.zig");
|
||||||
|
|
||||||
// See build_config.ExeEntrypoint for why we do this.
|
/// See build_config.ExeEntrypoint for why we do this.
|
||||||
pub usingnamespace switch (build_config.exe_entrypoint) {
|
const entrypoint = switch (build_config.exe_entrypoint) {
|
||||||
.ghostty => @import("main_ghostty.zig"),
|
.ghostty => @import("main_ghostty.zig"),
|
||||||
.helpgen => @import("helpgen.zig"),
|
.helpgen => @import("helpgen.zig"),
|
||||||
.mdgen_ghostty_1 => @import("build/mdgen/main_ghostty_1.zig"),
|
.mdgen_ghostty_1 => @import("build/mdgen/main_ghostty_1.zig"),
|
||||||
@ -12,3 +12,10 @@ pub usingnamespace switch (build_config.exe_entrypoint) {
|
|||||||
.bench_grapheme_break => @import("bench/grapheme-break.zig"),
|
.bench_grapheme_break => @import("bench/grapheme-break.zig"),
|
||||||
.bench_page_init => @import("bench/page-init.zig"),
|
.bench_page_init => @import("bench/page-init.zig"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The main entrypoint for the program.
|
||||||
|
pub const main = entrypoint.main;
|
||||||
|
|
||||||
|
test {
|
||||||
|
_ = entrypoint;
|
||||||
|
}
|
||||||
|
@ -21,12 +21,7 @@ const apprt = @import("apprt.zig");
|
|||||||
|
|
||||||
const App = @import("App.zig");
|
const App = @import("App.zig");
|
||||||
const Ghostty = @import("main_c.zig").Ghostty;
|
const Ghostty = @import("main_c.zig").Ghostty;
|
||||||
|
const state = &@import("global.zig").state;
|
||||||
/// Global process state. This is initialized in main() for exe artifacts
|
|
||||||
/// and by ghostty_init() for lib artifacts. This should ONLY be used by
|
|
||||||
/// the C API. The Zig API should NOT use any global state and should
|
|
||||||
/// rely on allocators being passed in as parameters.
|
|
||||||
pub var state: GlobalState = undefined;
|
|
||||||
|
|
||||||
/// The return type for main() depends on the build artifact. The lib build
|
/// The return type for main() depends on the build artifact. The lib build
|
||||||
/// also calls "main" in order to run the CLI actions, but it calls it as
|
/// also calls "main" in order to run the CLI actions, but it calls it as
|
||||||
@ -172,136 +167,6 @@ pub const std_options: std.Options = .{
|
|||||||
.logFn = logFn,
|
.logFn = logFn,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This represents the global process state. There should only
|
|
||||||
/// be one of these at any given moment. This is extracted into a dedicated
|
|
||||||
/// struct because it is reused by main and the static C lib.
|
|
||||||
pub const GlobalState = struct {
|
|
||||||
const GPA = std.heap.GeneralPurposeAllocator(.{});
|
|
||||||
|
|
||||||
gpa: ?GPA,
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
action: ?cli.Action,
|
|
||||||
logging: Logging,
|
|
||||||
|
|
||||||
/// The app resources directory, equivalent to zig-out/share when we build
|
|
||||||
/// from source. This is null if we can't detect it.
|
|
||||||
resources_dir: ?[]const u8,
|
|
||||||
|
|
||||||
/// Where logging should go
|
|
||||||
pub const Logging = union(enum) {
|
|
||||||
disabled: void,
|
|
||||||
stderr: void,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Initialize the global state.
|
|
||||||
pub fn init(self: *GlobalState) !void {
|
|
||||||
// Initialize ourself to nothing so we don't have any extra state.
|
|
||||||
// IMPORTANT: this MUST be initialized before any log output because
|
|
||||||
// the log function uses the global state.
|
|
||||||
self.* = .{
|
|
||||||
.gpa = null,
|
|
||||||
.alloc = undefined,
|
|
||||||
.action = null,
|
|
||||||
.logging = .{ .stderr = {} },
|
|
||||||
.resources_dir = null,
|
|
||||||
};
|
|
||||||
errdefer self.deinit();
|
|
||||||
|
|
||||||
self.gpa = gpa: {
|
|
||||||
// Use the libc allocator if it is available because it is WAY
|
|
||||||
// faster than GPA. We only do this in release modes so that we
|
|
||||||
// can get easy memory leak detection in debug modes.
|
|
||||||
if (builtin.link_libc) {
|
|
||||||
if (switch (builtin.mode) {
|
|
||||||
.ReleaseSafe, .ReleaseFast => true,
|
|
||||||
|
|
||||||
// We also use it if we can detect we're running under
|
|
||||||
// Valgrind since Valgrind only instruments the C allocator
|
|
||||||
else => std.valgrind.runningOnValgrind() > 0,
|
|
||||||
}) break :gpa null;
|
|
||||||
}
|
|
||||||
|
|
||||||
break :gpa GPA{};
|
|
||||||
};
|
|
||||||
|
|
||||||
self.alloc = if (self.gpa) |*value|
|
|
||||||
value.allocator()
|
|
||||||
else if (builtin.link_libc)
|
|
||||||
std.heap.c_allocator
|
|
||||||
else
|
|
||||||
unreachable;
|
|
||||||
|
|
||||||
// We first try to parse any action that we may be executing.
|
|
||||||
self.action = try cli.Action.detectCLI(self.alloc);
|
|
||||||
|
|
||||||
// If we have an action executing, we disable logging by default
|
|
||||||
// since we write to stderr we don't want logs messing up our
|
|
||||||
// output.
|
|
||||||
if (self.action != null) self.logging = .{ .disabled = {} };
|
|
||||||
|
|
||||||
// For lib mode we always disable stderr logging by default.
|
|
||||||
if (comptime build_config.app_runtime == .none) {
|
|
||||||
self.logging = .{ .disabled = {} };
|
|
||||||
}
|
|
||||||
|
|
||||||
// I don't love the env var name but I don't have it in my heart
|
|
||||||
// to parse CLI args 3 times (once for actions, once for config,
|
|
||||||
// maybe once for logging) so for now this is an easy way to do
|
|
||||||
// this. Env vars are useful for logging too because they are
|
|
||||||
// easy to set.
|
|
||||||
if ((try internal_os.getenv(self.alloc, "GHOSTTY_LOG"))) |v| {
|
|
||||||
defer v.deinit(self.alloc);
|
|
||||||
if (v.value.len > 0) {
|
|
||||||
self.logging = .{ .stderr = {} };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output some debug information right away
|
|
||||||
std.log.info("ghostty version={s}", .{build_config.version_string});
|
|
||||||
std.log.info("ghostty build optimize={s}", .{build_config.mode_string});
|
|
||||||
std.log.info("runtime={}", .{build_config.app_runtime});
|
|
||||||
std.log.info("font_backend={}", .{build_config.font_backend});
|
|
||||||
if (comptime build_config.font_backend.hasHarfbuzz()) {
|
|
||||||
std.log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()});
|
|
||||||
}
|
|
||||||
if (comptime build_config.font_backend.hasFontconfig()) {
|
|
||||||
std.log.info("dependency fontconfig={d}", .{fontconfig.version()});
|
|
||||||
}
|
|
||||||
std.log.info("renderer={}", .{renderer.Renderer});
|
|
||||||
std.log.info("libxev backend={}", .{xev.backend});
|
|
||||||
|
|
||||||
// First things first, we fix our file descriptors
|
|
||||||
internal_os.fixMaxFiles();
|
|
||||||
|
|
||||||
// We need to make sure the process locale is set properly. Locale
|
|
||||||
// affects a lot of behaviors in a shell.
|
|
||||||
try internal_os.ensureLocale(self.alloc);
|
|
||||||
|
|
||||||
// Initialize glslang for shader compilation
|
|
||||||
try glslang.init();
|
|
||||||
|
|
||||||
// Initialize oniguruma for regex
|
|
||||||
try oni.init(&.{oni.Encoding.utf8});
|
|
||||||
|
|
||||||
// Find our resources directory once for the app so every launch
|
|
||||||
// hereafter can use this cached value.
|
|
||||||
self.resources_dir = try internal_os.resourcesDir(self.alloc);
|
|
||||||
errdefer if (self.resources_dir) |dir| self.alloc.free(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Cleans up the global state. This doesn't _need_ to be called but
|
|
||||||
/// doing so in dev modes will check for memory leaks.
|
|
||||||
pub fn deinit(self: *GlobalState) void {
|
|
||||||
if (self.resources_dir) |dir| self.alloc.free(dir);
|
|
||||||
|
|
||||||
if (self.gpa) |*value| {
|
|
||||||
// We want to ensure that we deinit the GPA because this is
|
|
||||||
// the point at which it will output if there were safety violations.
|
|
||||||
_ = value.deinit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("circ_buf.zig");
|
_ = @import("circ_buf.zig");
|
||||||
_ = @import("pty.zig");
|
_ = @import("pty.zig");
|
||||||
|
Reference in New Issue
Block a user