diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 69bcbcb84..a8cee90fb 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -581,7 +581,7 @@ fn printCell( if (unmapped_c > std.math.maxInt(u8)) break :c ' '; // Get our lookup table and map it - const table = set.table(); + const table = charsets.table(set); break :c @intCast(table[@intCast(unmapped_c)]); }; diff --git a/src/terminal/charsets.zig b/src/terminal/charsets.zig index 9d49832df..b4fd58efc 100644 --- a/src/terminal/charsets.zig +++ b/src/terminal/charsets.zig @@ -16,76 +16,74 @@ pub const ActiveSlot = LibEnum( ); /// The list of supported character sets and their associated tables. -pub const Charset = enum { - utf8, - ascii, - british, - dec_special, +pub const Charset = LibEnum( + if (build_options.c_abi) .c else .zig, + &.{ "utf8", "ascii", "british", "dec_special" }, +); - /// The table for the given charset. This returns a pointer to a - /// slice that is guaranteed to be 255 chars that can be used to map - /// ASCII to the given charset. - pub fn table(set: Charset) []const u16 { - return switch (set) { - .british => &british, - .dec_special => &dec_special, +/// The table for the given charset. This returns a pointer to a +/// slice that is guaranteed to be 255 chars that can be used to map +/// ASCII to the given charset. +pub fn table(set: Charset) []const u16 { + return switch (set) { + .british => &british, + .dec_special => &dec_special, - // utf8 is not a table, callers should double-check if the - // charset is utf8 and NOT use tables. - .utf8 => unreachable, + // utf8 is not a table, callers should double-check if the + // charset is utf8 and NOT use tables. + .utf8 => unreachable, - // recommended that callers just map ascii directly but we can - // support a table - .ascii => &ascii, - }; - } -}; + // recommended that callers just map ascii directly but we can + // support a table + .ascii => &ascii, + }; +} /// Just a basic c => c ascii table const ascii = initTable(); /// https://vt100.net/docs/vt220-rm/chapter2.html const british = british: { - var table = initTable(); - table[0x23] = 0x00a3; - break :british table; + var tbl = initTable(); + tbl[0x23] = 0x00a3; + break :british tbl; }; /// https://en.wikipedia.org/wiki/DEC_Special_Graphics const dec_special = tech: { - var table = initTable(); - table[0x60] = 0x25C6; - table[0x61] = 0x2592; - table[0x62] = 0x2409; - table[0x63] = 0x240C; - table[0x64] = 0x240D; - table[0x65] = 0x240A; - table[0x66] = 0x00B0; - table[0x67] = 0x00B1; - table[0x68] = 0x2424; - table[0x69] = 0x240B; - table[0x6a] = 0x2518; - table[0x6b] = 0x2510; - table[0x6c] = 0x250C; - table[0x6d] = 0x2514; - table[0x6e] = 0x253C; - table[0x6f] = 0x23BA; - table[0x70] = 0x23BB; - table[0x71] = 0x2500; - table[0x72] = 0x23BC; - table[0x73] = 0x23BD; - table[0x74] = 0x251C; - table[0x75] = 0x2524; - table[0x76] = 0x2534; - table[0x77] = 0x252C; - table[0x78] = 0x2502; - table[0x79] = 0x2264; - table[0x7a] = 0x2265; - table[0x7b] = 0x03C0; - table[0x7c] = 0x2260; - table[0x7d] = 0x00A3; - table[0x7e] = 0x00B7; - break :tech table; + var tbl = initTable(); + tbl[0x60] = 0x25C6; + tbl[0x61] = 0x2592; + tbl[0x62] = 0x2409; + tbl[0x63] = 0x240C; + tbl[0x64] = 0x240D; + tbl[0x65] = 0x240A; + tbl[0x66] = 0x00B0; + tbl[0x67] = 0x00B1; + tbl[0x68] = 0x2424; + tbl[0x69] = 0x240B; + tbl[0x6a] = 0x2518; + tbl[0x6b] = 0x2510; + tbl[0x6c] = 0x250C; + tbl[0x6d] = 0x2514; + tbl[0x6e] = 0x253C; + tbl[0x6f] = 0x23BA; + tbl[0x70] = 0x23BB; + tbl[0x71] = 0x2500; + tbl[0x72] = 0x23BC; + tbl[0x73] = 0x23BD; + tbl[0x74] = 0x251C; + tbl[0x75] = 0x2524; + tbl[0x76] = 0x2534; + tbl[0x77] = 0x252C; + tbl[0x78] = 0x2502; + tbl[0x79] = 0x2264; + tbl[0x7a] = 0x2265; + tbl[0x7b] = 0x03C0; + tbl[0x7c] = 0x2260; + tbl[0x7d] = 0x00A3; + tbl[0x7e] = 0x00B7; + break :tech tbl; }; /// Our table length is 256 so we can contain all ASCII chars. @@ -107,11 +105,11 @@ test { // utf8 has no table if (@field(Charset, field.name) == .utf8) continue; - const table = @field(Charset, field.name).table(); + const tbl = table(@field(Charset, field.name)); // Yes, I could use `table_len` here, but I want to explicitly use a // hardcoded constant so that if there are miscompilations or a comptime // issue, we catch it. - try testing.expectEqual(@as(usize, 256), table.len); + try testing.expectEqual(@as(usize, 256), tbl.len); } } diff --git a/src/terminal/main.zig b/src/terminal/main.zig index 59b5d0d53..5c19af023 100644 --- a/src/terminal/main.zig +++ b/src/terminal/main.zig @@ -25,6 +25,7 @@ pub const x11_color = @import("x11_color.zig"); pub const Charset = charsets.Charset; pub const CharsetSlot = charsets.Slots; pub const CharsetActiveSlot = charsets.ActiveSlot; +pub const charsetTable = charsets.table; pub const Cell = page.Cell; pub const Coordinate = point.Coordinate; pub const CSI = Parser.Action.CSI; diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index 025e995c1..d4d61f62b 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -123,6 +123,7 @@ pub const Action = union(Key) { prompt_continuation: PromptContinuation, end_of_command: EndOfCommand, mouse_shape: MouseShape, + configure_charset: ConfigureCharset, pub const Key = lib.Enum( lib_target, @@ -220,6 +221,7 @@ pub const Action = union(Key) { "prompt_continuation", "end_of_command", "mouse_shape", + "configure_charset", }, ); @@ -420,6 +422,11 @@ pub const Action = union(Key) { }; } }; + + pub const ConfigureCharset = lib.Struct(lib_target, struct { + slot: charsets.Slots, + charset: charsets.Charset, + }); }; /// Returns a type that can process a stream of tty control characters. @@ -1981,14 +1988,9 @@ pub fn Stream(comptime Handler: type) type { }, }; - if (@hasDecl(T, "configureCharset")) { - try self.handler.configureCharset(slot, set); - return; - } - - log.warn("unimplemented configureCharset callback slot={} set={}", .{ - slot, - set, + try self.handler.vt(.configure_charset, .{ + .slot = slot, + .charset = set, }); } diff --git a/src/termio/stream_handler.zig b/src/termio/stream_handler.zig index d23e7606e..4e5795a10 100644 --- a/src/termio/stream_handler.zig +++ b/src/termio/stream_handler.zig @@ -316,6 +316,7 @@ pub const StreamHandler = struct { .prompt_continuation => self.promptContinuation(value.aid), .end_of_command => self.endOfCommand(value.exit_code), .mouse_shape => try self.setMouseShape(value), + .configure_charset => self.configureCharset(value.slot, value.charset), .dcs_hook => try self.dcsHook(value), .dcs_put => try self.dcsPut(value), .dcs_unhook => try self.dcsUnhook(), @@ -859,11 +860,11 @@ pub const StreamHandler = struct { self.messageWriter(try termio.Message.writeReq(self.alloc, self.enquiry_response)); } - pub fn configureCharset( + fn configureCharset( self: *StreamHandler, slot: terminal.CharsetSlot, set: terminal.Charset, - ) !void { + ) void { self.terminal.configureCharset(slot, set); }