From 40cec189432d28fdc6870db4352ca68785a862fa Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 2 Aug 2022 11:03:01 -0700 Subject: [PATCH] implement DECSASD by just blackholing the output for now We don't want to support status lines, and if anything sends us status line information we don't want it to mess up the main display, so just drop it. --- src/Window.zig | 7 +++++++ src/terminal/Terminal.zig | 8 ++++++++ src/terminal/ansi.zig | 19 +++++++++++++++++++ src/terminal/main.zig | 2 ++ src/terminal/stream.zig | 20 ++++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/src/Window.zig b/src/Window.zig index 8e04e7e42..4e904918a 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -925,3 +925,10 @@ pub fn restoreCursor(self: *Window) !void { pub fn enquiry(self: *Window) !void { try self.queueWrite(""); } + +pub fn setActiveStatusDisplay( + self: *Window, + req: terminal.StatusDisplay, +) !void { + self.terminal.status_display = req; +} diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index c224367da..1d22db940 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -35,6 +35,11 @@ active_screen: ScreenType, screen: Screen, secondary_screen: Screen, +/// Whether we're currently writing to the status line (DECSASD and DECSSDT). +/// We don't support a status line currently so we just black hole this +/// data so that it doesn't mess up our main display. +status_display: ansi.StatusDisplay = .main, + /// Where the tabstops are. tabstops: Tabstops, @@ -303,6 +308,9 @@ pub fn print(self: *Terminal, c: u21) !void { const tracy = trace(@src()); defer tracy.end(); + // If we're not on the main display, do nothing for now + if (self.status_display != .main) return; + // If we're not at the bottom, then we need to move there if (!self.screen.displayIsBottom()) self.screen.scroll(.{ .bottom = {} }); diff --git a/src/terminal/ansi.zig b/src/terminal/ansi.zig index 64f8eabe0..3186f322d 100644 --- a/src/terminal/ansi.zig +++ b/src/terminal/ansi.zig @@ -115,3 +115,22 @@ pub const CursorStyle = enum(u16) { }; } }; + +/// The status line type for DECSSDT. +pub const StatusLineType = enum(u16) { + none = 0, + indicator = 1, + host_writable = 2, + + // Non-exhaustive so that @intToEnum never fails for unsupported values. + _, +}; + +/// The display to target for status updates (DECSASD). +pub const StatusDisplay = enum(u16) { + main = 0, + status_line = 1, + + // Non-exhaustive so that @intToEnum never fails for unsupported values. + _, +}; diff --git a/src/terminal/main.zig b/src/terminal/main.zig index e0a56ea1b..fecb37e57 100644 --- a/src/terminal/main.zig +++ b/src/terminal/main.zig @@ -11,6 +11,8 @@ pub const CursorStyle = ansi.CursorStyle; pub const DeviceAttributeReq = ansi.DeviceAttributeReq; pub const DeviceStatusReq = ansi.DeviceStatusReq; pub const Mode = ansi.Mode; +pub const StatusLineType = ansi.StatusLineType; +pub const StatusDisplay = ansi.StatusDisplay; pub const EraseDisplay = csi.EraseDisplay; pub const EraseLine = csi.EraseLine; pub const TabClear = csi.TabClear; diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index 2b6a357f4..b8effd872 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -382,6 +382,26 @@ pub fn Stream(comptime Handler: type) type { 1 => try self.handler.insertBlanks(action.params[0]), else => log.warn("invalid ICH command: {}", .{action}), } else log.warn("unimplemented CSI callback: {}", .{action}), + + // DECSASD - Select Active Status Display + '}' => { + const success = decsasd: { + // Verify we're getting a DECSASD command + if (action.intermediates.len != 1 or action.intermediates[0] != '$') + break :decsasd false; + if (action.params.len != 1) + break :decsasd false; + if (!@hasDecl(T, "setActiveStatusDisplay")) + break :decsasd false; + + try self.handler.setActiveStatusDisplay( + @intToEnum(ansi.StatusDisplay, action.params[0]), + ); + break :decsasd true; + }; + + if (!success) log.warn("unimplemented CSI callback: {}", .{action}); + }, } }