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}); + }, } }