vaxis: enable da1 parsing, use futex timeout to return from query
Now that DA1 parsing is done, block the queryTerminal function until the DA1 response is received, or a 1 second timeout elapses. With this functionality, move certain events into Vaxis's realm of handling: IE enabling kitty keyboard, unicode mode, etc Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
parent
a2dc97c039
commit
04f6117cfe
7 changed files with 47 additions and 17 deletions
|
@ -61,8 +61,6 @@ pub fn main() !void {
|
||||||
.winsize => |ws| {
|
.winsize => |ws| {
|
||||||
try vx.resize(alloc, ws);
|
try vx.resize(alloc, ws);
|
||||||
},
|
},
|
||||||
.cap_rgb => continue,
|
|
||||||
.cap_kitty_keyboard => try vx.enableKittyKeyboard(.{}),
|
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +96,5 @@ const Event = union(enum) {
|
||||||
key_press: vaxis.Key,
|
key_press: vaxis.Key,
|
||||||
winsize: vaxis.Winsize,
|
winsize: vaxis.Winsize,
|
||||||
focus_in,
|
focus_in,
|
||||||
cap_rgb,
|
|
||||||
cap_kitty_keyboard,
|
|
||||||
foo: u8,
|
foo: u8,
|
||||||
};
|
};
|
||||||
|
|
|
@ -357,6 +357,17 @@ pub fn parse(self: *Parser, input: []const u8) !Result {
|
||||||
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
||||||
return .{ .event = null, .n = i + 1 };
|
return .{ .event = null, .n = i + 1 };
|
||||||
},
|
},
|
||||||
|
'c' => { // DA1 response
|
||||||
|
const priv = seq.private_indicator orelse {
|
||||||
|
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
||||||
|
return .{ .event = null, .n = i + 1 };
|
||||||
|
};
|
||||||
|
if (priv != '?') {
|
||||||
|
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
||||||
|
return .{ .event = null, .n = i + 1 };
|
||||||
|
}
|
||||||
|
return .{ .event = .cap_da1, .n = i + 1 };
|
||||||
|
},
|
||||||
else => {
|
else => {
|
||||||
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
||||||
return .{
|
return .{
|
||||||
|
|
15
src/Tty.zig
15
src/Tty.zig
|
@ -178,19 +178,16 @@ pub fn run(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.cap_kitty_keyboard => {
|
.cap_kitty_keyboard => {
|
||||||
if (@hasField(EventType, "cap_kitty_keyboard")) {
|
vx.caps.kitty_keyboard = true;
|
||||||
vx.postEvent(.cap_kitty_keyboard);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
.cap_rgb => {
|
.cap_rgb => {
|
||||||
if (@hasField(EventType, "cap_rgb")) {
|
vx.caps.rgb = true;
|
||||||
vx.postEvent(.cap_rgb);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
.cap_unicode => {
|
.cap_unicode => {
|
||||||
if (@hasField(EventType, "cap_unicode")) {
|
vx.caps.unicode = true;
|
||||||
vx.postEvent(.cap_unicode);
|
},
|
||||||
}
|
.cap_da1 => {
|
||||||
|
std.Thread.Futex.wake(&vx.query_futex, 10);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ pub const sixel_geometry_query = "\x1b[?2;1;0S";
|
||||||
pub const sync_set = "\x1b[?2026h";
|
pub const sync_set = "\x1b[?2026h";
|
||||||
pub const sync_reset = "\x1b[?2026l";
|
pub const sync_reset = "\x1b[?2026l";
|
||||||
|
|
||||||
|
pub const unicode_set = "\x1b[?2027h";
|
||||||
|
pub const unicode_reset = "\x1b[?2027l";
|
||||||
|
|
||||||
// Key encoding
|
// Key encoding
|
||||||
pub const csi_u_push = "\x1b[>{d}u";
|
pub const csi_u_push = "\x1b[>{d}u";
|
||||||
pub const csi_u_pop = "\x1b[<u";
|
pub const csi_u_pop = "\x1b[<u";
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
pub const Key = @import("Key.zig");
|
pub const Key = @import("Key.zig");
|
||||||
|
|
||||||
/// The events that Vaxis emits. This can be used as the generic EventType if
|
/// The events that Vaxis emits internally
|
||||||
/// there are no internal events
|
|
||||||
pub const Event = union(enum) {
|
pub const Event = union(enum) {
|
||||||
key_press: Key,
|
key_press: Key,
|
||||||
focus_in,
|
focus_in,
|
||||||
|
@ -13,4 +12,5 @@ pub const Event = union(enum) {
|
||||||
cap_kitty_keyboard,
|
cap_kitty_keyboard,
|
||||||
cap_rgb,
|
cap_rgb,
|
||||||
cap_unicode,
|
cap_unicode,
|
||||||
|
cap_da1,
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,6 @@ pub const Style = cell.Style;
|
||||||
|
|
||||||
pub const Key = @import("Key.zig");
|
pub const Key = @import("Key.zig");
|
||||||
pub const Winsize = @import("Tty.zig").Winsize;
|
pub const Winsize = @import("Tty.zig").Winsize;
|
||||||
pub const Event = @import("event.zig").Event;
|
|
||||||
|
|
||||||
pub const widgets = @import("widgets/main.zig");
|
pub const widgets = @import("widgets/main.zig");
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const atomic = std.atomic;
|
||||||
|
|
||||||
const Queue = @import("queue.zig").Queue;
|
const Queue = @import("queue.zig").Queue;
|
||||||
const ctlseqs = @import("ctlseqs.zig");
|
const ctlseqs = @import("ctlseqs.zig");
|
||||||
|
@ -30,6 +31,12 @@ pub fn Vaxis(comptime T: type) type {
|
||||||
|
|
||||||
pub const EventType = T;
|
pub const EventType = T;
|
||||||
|
|
||||||
|
pub const Capabilities = struct {
|
||||||
|
kitty_keyboard: bool = false,
|
||||||
|
rgb: bool = false,
|
||||||
|
unicode: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
/// the event queue for Vaxis
|
/// the event queue for Vaxis
|
||||||
//
|
//
|
||||||
// TODO: is 512 ok?
|
// TODO: is 512 ok?
|
||||||
|
@ -49,9 +56,15 @@ pub fn Vaxis(comptime T: type) type {
|
||||||
/// if we have entered kitty keyboard
|
/// if we have entered kitty keyboard
|
||||||
kitty_keyboard: bool = false,
|
kitty_keyboard: bool = false,
|
||||||
|
|
||||||
|
caps: Capabilities = .{},
|
||||||
|
|
||||||
/// if we should redraw the entire screen on the next render
|
/// if we should redraw the entire screen on the next render
|
||||||
refresh: bool = false,
|
refresh: bool = false,
|
||||||
|
|
||||||
|
/// blocks the main thread until a DA1 query has been received, or the
|
||||||
|
/// futex times out
|
||||||
|
query_futex: atomic.Value(u32) = atomic.Value(u32).init(0),
|
||||||
|
|
||||||
// statistics
|
// statistics
|
||||||
renders: usize = 0,
|
renders: usize = 0,
|
||||||
render_dur: i128 = 0,
|
render_dur: i128 = 0,
|
||||||
|
@ -201,6 +214,17 @@ pub fn Vaxis(comptime T: type) type {
|
||||||
|
|
||||||
_ = try tty.write(ctlseqs.primary_device_attrs);
|
_ = try tty.write(ctlseqs.primary_device_attrs);
|
||||||
try tty.flush();
|
try tty.flush();
|
||||||
|
|
||||||
|
// 1 second timeout
|
||||||
|
std.Thread.Futex.timedWait(&self.query_futex, 0, 1 * std.time.ns_per_s) catch {};
|
||||||
|
|
||||||
|
// enable detected features
|
||||||
|
if (self.caps.kitty_keyboard) {
|
||||||
|
try self.enableKittyKeyboard(.{});
|
||||||
|
}
|
||||||
|
if (self.caps.unicode) {
|
||||||
|
_ = try tty.write(ctlseqs.unicode_set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the next render call will refresh the entire screen
|
// the next render call will refresh the entire screen
|
||||||
|
@ -429,7 +453,7 @@ pub fn Vaxis(comptime T: type) type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enableKittyKeyboard(self: *Self, flags: Key.KittyFlags) !void {
|
fn enableKittyKeyboard(self: *Self, flags: Key.KittyFlags) !void {
|
||||||
self.kitty_keyboard = true;
|
self.kitty_keyboard = true;
|
||||||
const flag_int: u5 = @bitCast(flags);
|
const flag_int: u5 = @bitCast(flags);
|
||||||
try std.fmt.format(
|
try std.fmt.format(
|
||||||
|
|
Loading…
Reference in a new issue