aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/terminal/c/osc.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/terminal/c/osc.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/terminal/c/osc.zig')
-rw-r--r--vendor/libghostty-vt/src/terminal/c/osc.zig140
1 files changed, 140 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/terminal/c/osc.zig b/vendor/libghostty-vt/src/terminal/c/osc.zig
new file mode 100644
index 00000000..7ba32300
--- /dev/null
+++ b/vendor/libghostty-vt/src/terminal/c/osc.zig
@@ -0,0 +1,140 @@
+const std = @import("std");
+const lib = @import("../lib.zig");
+const CAllocator = lib.alloc.Allocator;
+const osc = @import("../osc.zig");
+const Result = @import("result.zig").Result;
+
+const log = std.log.scoped(.osc);
+
+/// C: GhosttyOscParser
+pub const Parser = ?*osc.Parser;
+
+/// C: GhosttyOscCommand
+pub const Command = ?*osc.Command;
+
+pub fn new(
+ alloc_: ?*const CAllocator,
+ result: *Parser,
+) callconv(lib.calling_conv) Result {
+ const alloc = lib.alloc.default(alloc_);
+ const ptr = alloc.create(osc.Parser) catch
+ return .out_of_memory;
+ ptr.* = .init(alloc);
+ result.* = ptr;
+ return .success;
+}
+
+pub fn free(parser_: Parser) callconv(lib.calling_conv) void {
+ // C-built parsers always have an associated allocator.
+ const parser = parser_ orelse return;
+ const alloc = parser.alloc.?;
+ parser.deinit();
+ alloc.destroy(parser);
+}
+
+pub fn reset(parser_: Parser) callconv(lib.calling_conv) void {
+ parser_.?.reset();
+}
+
+pub fn next(parser_: Parser, byte: u8) callconv(lib.calling_conv) void {
+ parser_.?.next(byte);
+}
+
+pub fn end(parser_: Parser, terminator: u8) callconv(lib.calling_conv) Command {
+ return parser_.?.end(terminator);
+}
+
+pub fn commandType(command_: Command) callconv(lib.calling_conv) osc.Command.Key {
+ const command = command_ orelse return .invalid;
+ return command.*;
+}
+
+/// C: GhosttyOscCommandData
+pub const CommandData = enum(c_int) {
+ invalid = 0,
+ change_window_title_str = 1,
+
+ /// Output type expected for querying the data of the given kind.
+ pub fn OutType(comptime self: CommandData) type {
+ return switch (self) {
+ .invalid => void,
+ .change_window_title_str => [*:0]const u8,
+ };
+ }
+};
+
+pub fn commandData(
+ command_: Command,
+ data: CommandData,
+ out: ?*anyopaque,
+) callconv(lib.calling_conv) bool {
+ if (comptime std.debug.runtime_safety) {
+ _ = std.meta.intToEnum(CommandData, @intFromEnum(data)) catch {
+ log.warn("commandData invalid data value={d}", .{@intFromEnum(data)});
+ return false;
+ };
+ }
+
+ return switch (data) {
+ .invalid => false,
+ inline else => |comptime_data| commandDataTyped(
+ command_,
+ comptime_data,
+ @ptrCast(@alignCast(out)),
+ ),
+ };
+}
+
+fn commandDataTyped(
+ command_: Command,
+ comptime data: CommandData,
+ out: *data.OutType(),
+) bool {
+ const command = command_.?;
+ switch (data) {
+ .invalid => return false,
+ .change_window_title_str => switch (command.*) {
+ .change_window_title => |v| out.* = v.ptr,
+ else => return false,
+ },
+ }
+
+ return true;
+}
+
+test "alloc" {
+ const testing = std.testing;
+ var p: Parser = undefined;
+ try testing.expectEqual(Result.success, new(
+ &lib.alloc.test_allocator,
+ &p,
+ ));
+ free(p);
+}
+
+test "command type null" {
+ const testing = std.testing;
+ try testing.expectEqual(.invalid, commandType(null));
+}
+
+test "change window title" {
+ const testing = std.testing;
+ var p: Parser = undefined;
+ try testing.expectEqual(Result.success, new(
+ &lib.alloc.test_allocator,
+ &p,
+ ));
+ defer free(p);
+
+ // Parse it
+ next(p, '0');
+ next(p, ';');
+ next(p, 'a');
+ const cmd = end(p, 0);
+ try testing.expectEqual(.change_window_title, commandType(cmd));
+
+ // Extract the title
+ var title: [*:0]const u8 = undefined;
+ try testing.expect(commandData(cmd, .change_window_title_str, @ptrCast(&title)));
+ try testing.expectEqualStrings("a", std.mem.span(title));
+}