terminal: request mode
parent
b6ac4c764f
commit
25eee9379d
|
|
@ -73,6 +73,8 @@ pub const Action = union(Key) {
|
|||
reset_mode: Mode,
|
||||
save_mode: Mode,
|
||||
restore_mode: Mode,
|
||||
request_mode: Mode,
|
||||
request_mode_unknown: RawMode,
|
||||
modify_key_format: ansi.ModifyKeyFormat,
|
||||
|
||||
pub const Key = lib.Enum(
|
||||
|
|
@ -121,6 +123,8 @@ pub const Action = union(Key) {
|
|||
"reset_mode",
|
||||
"save_mode",
|
||||
"restore_mode",
|
||||
"request_mode",
|
||||
"request_mode_unknown",
|
||||
"modify_key_format",
|
||||
},
|
||||
);
|
||||
|
|
@ -180,6 +184,11 @@ pub const Action = union(Key) {
|
|||
return @bitCast(self.mode);
|
||||
}
|
||||
};
|
||||
|
||||
pub const RawMode = extern struct {
|
||||
mode: u16,
|
||||
ansi: bool,
|
||||
};
|
||||
};
|
||||
|
||||
/// Returns a type that can process a stream of tty control characters.
|
||||
|
|
@ -1242,9 +1251,16 @@ pub fn Stream(comptime Handler: type) type {
|
|||
break :decrqm;
|
||||
}
|
||||
|
||||
if (@hasDecl(T, "requestMode")) {
|
||||
try self.handler.requestMode(input.params[0], ansi_mode);
|
||||
} else log.warn("unimplemented DECRQM callback: {f}", .{input});
|
||||
const mode_raw = input.params[0];
|
||||
const mode = modes.modeFromInt(mode_raw, ansi_mode);
|
||||
if (mode) |m| {
|
||||
try self.handler.vt(.request_mode, .{ .mode = m });
|
||||
} else {
|
||||
try self.handler.vt(.request_mode_unknown, .{
|
||||
.mode = mode_raw,
|
||||
.ansi = ansi_mode,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
else => log.warn(
|
||||
|
|
|
|||
|
|
@ -253,6 +253,8 @@ pub const StreamHandler = struct {
|
|||
const v = self.terminal.modes.restore(value.mode);
|
||||
try self.setMode(value.mode, v);
|
||||
},
|
||||
.request_mode => try self.requestMode(value.mode),
|
||||
.request_mode_unknown => try self.requestModeUnknown(value.mode, value.ansi),
|
||||
.modify_key_format => try self.setModifyKeyFormat(value),
|
||||
}
|
||||
}
|
||||
|
|
@ -456,22 +458,32 @@ pub const StreamHandler = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn requestMode(self: *StreamHandler, mode_raw: u16, ansi: bool) !void {
|
||||
// Get the mode value and respond.
|
||||
const code: u8 = code: {
|
||||
const mode = terminal.modes.modeFromInt(mode_raw, ansi) orelse break :code 0;
|
||||
if (self.terminal.modes.get(mode)) break :code 1;
|
||||
break :code 2;
|
||||
};
|
||||
fn requestMode(self: *StreamHandler, mode: terminal.Mode) !void {
|
||||
const tag: terminal.modes.ModeTag = @bitCast(@intFromEnum(mode));
|
||||
const code: u8 = if (self.terminal.modes.get(mode)) 1 else 2;
|
||||
|
||||
var msg: termio.Message = .{ .write_small = .{} };
|
||||
const resp = try std.fmt.bufPrint(
|
||||
&msg.write_small.data,
|
||||
"\x1B[{s}{};{}$y",
|
||||
.{
|
||||
if (tag.ansi) "" else "?",
|
||||
tag.value,
|
||||
code,
|
||||
},
|
||||
);
|
||||
msg.write_small.len = @intCast(resp.len);
|
||||
self.messageWriter(msg);
|
||||
}
|
||||
|
||||
fn requestModeUnknown(self: *StreamHandler, mode_raw: u16, ansi: bool) !void {
|
||||
var msg: termio.Message = .{ .write_small = .{} };
|
||||
const resp = try std.fmt.bufPrint(
|
||||
&msg.write_small.data,
|
||||
"\x1B[{s}{};0$y",
|
||||
.{
|
||||
if (ansi) "" else "?",
|
||||
mode_raw,
|
||||
code,
|
||||
},
|
||||
);
|
||||
msg.write_small.len = @intCast(resp.len);
|
||||
|
|
|
|||
Loading…
Reference in New Issue