this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+47 -17
-4
examples/text_input.zig
··· 61 61 .winsize => |ws| { 62 62 try vx.resize(alloc, ws); 63 63 }, 64 - .cap_rgb => continue, 65 - .cap_kitty_keyboard => try vx.enableKittyKeyboard(.{}), 66 64 else => {}, 67 65 } 68 66 ··· 98 96 key_press: vaxis.Key, 99 97 winsize: vaxis.Winsize, 100 98 focus_in, 101 - cap_rgb, 102 - cap_kitty_keyboard, 103 99 foo: u8, 104 100 };
+11
src/Parser.zig
··· 357 357 log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]}); 358 358 return .{ .event = null, .n = i + 1 }; 359 359 }, 360 + 'c' => { // DA1 response 361 + const priv = seq.private_indicator orelse { 362 + log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]}); 363 + return .{ .event = null, .n = i + 1 }; 364 + }; 365 + if (priv != '?') { 366 + log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]}); 367 + return .{ .event = null, .n = i + 1 }; 368 + } 369 + return .{ .event = .cap_da1, .n = i + 1 }; 370 + }, 360 371 else => { 361 372 log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]}); 362 373 return .{
+6 -9
src/Tty.zig
··· 178 178 } 179 179 }, 180 180 .cap_kitty_keyboard => { 181 - if (@hasField(EventType, "cap_kitty_keyboard")) { 182 - vx.postEvent(.cap_kitty_keyboard); 183 - } 181 + vx.caps.kitty_keyboard = true; 184 182 }, 185 183 .cap_rgb => { 186 - if (@hasField(EventType, "cap_rgb")) { 187 - vx.postEvent(.cap_rgb); 188 - } 184 + vx.caps.rgb = true; 189 185 }, 190 186 .cap_unicode => { 191 - if (@hasField(EventType, "cap_unicode")) { 192 - vx.postEvent(.cap_unicode); 193 - } 187 + vx.caps.unicode = true; 188 + }, 189 + .cap_da1 => { 190 + std.Thread.Futex.wake(&vx.query_futex, 10); 194 191 }, 195 192 } 196 193 }
+3
src/ctlseqs.zig
··· 14 14 pub const sync_set = "\x1b[?2026h"; 15 15 pub const sync_reset = "\x1b[?2026l"; 16 16 17 + pub const unicode_set = "\x1b[?2027h"; 18 + pub const unicode_reset = "\x1b[?2027l"; 19 + 17 20 // Key encoding 18 21 pub const csi_u_push = "\x1b[>{d}u"; 19 22 pub const csi_u_pop = "\x1b[<u";
+2 -2
src/event.zig
··· 1 1 pub const Key = @import("Key.zig"); 2 2 3 - /// The events that Vaxis emits. This can be used as the generic EventType if 4 - /// there are no internal events 3 + /// The events that Vaxis emits internally 5 4 pub const Event = union(enum) { 6 5 key_press: Key, 7 6 focus_in, ··· 13 12 cap_kitty_keyboard, 14 13 cap_rgb, 15 14 cap_unicode, 15 + cap_da1, 16 16 };
-1
src/main.zig
··· 7 7 8 8 pub const Key = @import("Key.zig"); 9 9 pub const Winsize = @import("Tty.zig").Winsize; 10 - pub const Event = @import("event.zig").Event; 11 10 12 11 pub const widgets = @import("widgets/main.zig"); 13 12
+25 -1
src/vaxis.zig
··· 1 1 const std = @import("std"); 2 + const atomic = std.atomic; 2 3 3 4 const Queue = @import("queue.zig").Queue; 4 5 const ctlseqs = @import("ctlseqs.zig"); ··· 29 30 const log = std.log.scoped(.vaxis); 30 31 31 32 pub const EventType = T; 33 + 34 + pub const Capabilities = struct { 35 + kitty_keyboard: bool = false, 36 + rgb: bool = false, 37 + unicode: bool = false, 38 + }; 32 39 33 40 /// the event queue for Vaxis 34 41 // ··· 49 56 /// if we have entered kitty keyboard 50 57 kitty_keyboard: bool = false, 51 58 59 + caps: Capabilities = .{}, 60 + 52 61 /// if we should redraw the entire screen on the next render 53 62 refresh: bool = false, 63 + 64 + /// blocks the main thread until a DA1 query has been received, or the 65 + /// futex times out 66 + query_futex: atomic.Value(u32) = atomic.Value(u32).init(0), 54 67 55 68 // statistics 56 69 renders: usize = 0, ··· 201 214 202 215 _ = try tty.write(ctlseqs.primary_device_attrs); 203 216 try tty.flush(); 217 + 218 + // 1 second timeout 219 + std.Thread.Futex.timedWait(&self.query_futex, 0, 1 * std.time.ns_per_s) catch {}; 220 + 221 + // enable detected features 222 + if (self.caps.kitty_keyboard) { 223 + try self.enableKittyKeyboard(.{}); 224 + } 225 + if (self.caps.unicode) { 226 + _ = try tty.write(ctlseqs.unicode_set); 227 + } 204 228 } 205 229 206 230 // the next render call will refresh the entire screen ··· 429 453 } 430 454 } 431 455 432 - pub fn enableKittyKeyboard(self: *Self, flags: Key.KittyFlags) !void { 456 + fn enableKittyKeyboard(self: *Self, flags: Key.KittyFlags) !void { 433 457 self.kitty_keyboard = true; 434 458 const flag_int: u5 = @bitCast(flags); 435 459 try std.fmt.format(