summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-11-04 22:13:37 -0700
committerMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-11-05 19:31:02 -0700
commit989046a06cda2b915e487b4bc63f8bb062eafcd3 (patch)
tree444b7abd5dbf4c269cd22789658de3600ab0805d /src
parent1a7b9f7465302ed55511b79535208960807cc6f1 (diff)
More IO events
Diffstat (limited to 'src')
-rw-r--r--src/Window.zig18
-rw-r--r--src/main.zig1
-rw-r--r--src/termio/Exec.zig26
-rw-r--r--src/termio/Thread.zig2
-rw-r--r--src/termio/message.zig21
5 files changed, 63 insertions, 5 deletions
diff --git a/src/Window.zig b/src/Window.zig
index 3930f21ba..a9aafa5ca 100644
--- a/src/Window.zig
+++ b/src/Window.zig
@@ -815,6 +815,24 @@ fn charCallback(window: glfw.Window, codepoint: u21) void {
.clear_selection = {},
}, .{ .forever = {} });
+ // Scroll to the bottom
+ _ = win.io_thread.mailbox.push(.{
+ .scroll_viewport = .{ .bottom = {} },
+ }, .{ .forever = {} });
+
+ // Write the char to the pty
+ var data: termio.message.IO.SmallWriteArray = undefined;
+ data[0] = @intCast(u8, codepoint);
+ _ = win.io_thread.mailbox.push(.{
+ .small_write = .{
+ .data = data,
+ .len = 1,
+ },
+ }, .{ .forever = {} });
+
+ // After sending all our messages we have to notify our IO thread
+ win.io_thread.wakeup.send() catch {};
+
// TODO: the stuff below goes away with IO thread
if (win.terminal.selection != null) {
diff --git a/src/main.zig b/src/main.zig
index 1f92efbe1..a985416cb 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -196,6 +196,7 @@ test {
_ = @import("font/main.zig");
_ = @import("renderer.zig");
_ = @import("terminal/Terminal.zig");
+ _ = @import("termio.zig");
_ = @import("input.zig");
// Libraries
diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig
index 8762cc56f..47675b16b 100644
--- a/src/termio/Exec.zig
+++ b/src/termio/Exec.zig
@@ -3,6 +3,7 @@ pub const Exec = @This();
const std = @import("std");
const builtin = @import("builtin");
+const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const termio = @import("../termio.zig");
const Command = @import("../Command.zig");
@@ -42,6 +43,9 @@ renderer_wakeup: libuv.Async,
/// The cached grid size whenever a resize is called.
grid_size: renderer.GridSize,
+/// The data associated with the currently running thread.
+data: ?*EventData,
+
/// Initialize the exec implementation. This will also start the child
/// process.
pub fn init(alloc: Allocator, opts: termio.Options) !Exec {
@@ -100,6 +104,7 @@ pub fn init(alloc: Allocator, opts: termio.Options) !Exec {
.renderer_state = opts.renderer_state,
.renderer_wakeup = opts.renderer_wakeup,
.grid_size = opts.grid_size,
+ .data = null,
};
}
@@ -115,6 +120,8 @@ pub fn deinit(self: *Exec) void {
}
pub fn threadEnter(self: *Exec, loop: libuv.Loop) !ThreadData {
+ assert(self.data == null);
+
// Get a copy to our allocator
const alloc_ptr = loop.getData(Allocator).?;
const alloc = alloc_ptr.*;
@@ -146,7 +153,10 @@ pub fn threadEnter(self: *Exec, loop: libuv.Loop) !ThreadData {
};
errdefer ev_data_ptr.deinit();
- // Return our data
+ // Store our data so our callbacks can access it
+ self.data = ev_data_ptr;
+
+ // Return our thread data
return ThreadData{
.alloc = alloc,
.ev = ev_data_ptr,
@@ -154,8 +164,9 @@ pub fn threadEnter(self: *Exec, loop: libuv.Loop) !ThreadData {
}
pub fn threadExit(self: *Exec, data: ThreadData) void {
- _ = self;
_ = data;
+
+ self.data = null;
}
/// Resize the terminal.
@@ -199,6 +210,17 @@ pub fn clearSelection(self: *Exec) !void {
}
}
+pub fn scrollViewport(self: *Exec, scroll: terminal.Terminal.ScrollViewport) !void {
+ self.renderer_state.mutex.lock();
+ defer self.renderer_state.mutex.unlock();
+
+ try self.terminal.scrollViewport(scroll);
+}
+
+pub inline fn queueWrite(self: *Exec, data: []const u8) !void {
+ try self.data.?.queueWrite(data);
+}
+
const ThreadData = struct {
/// Allocator used for the event data
alloc: Allocator,
diff --git a/src/termio/Thread.zig b/src/termio/Thread.zig
index d0dd76cfc..c05f3dbb8 100644
--- a/src/termio/Thread.zig
+++ b/src/termio/Thread.zig
@@ -163,6 +163,8 @@ fn drainMailbox(self: *Thread) !void {
switch (message) {
.resize => |v| try self.impl.resize(v.grid_size, v.screen_size),
.clear_selection => try self.impl.clearSelection(),
+ .scroll_viewport => |v| try self.impl.scrollViewport(v),
+ .small_write => |v| try self.impl.queueWrite(v.data[0..v.len]),
}
}
}
diff --git a/src/termio/message.zig b/src/termio/message.zig
index 966e5ccb6..b80ae2e4f 100644
--- a/src/termio/message.zig
+++ b/src/termio/message.zig
@@ -1,8 +1,11 @@
+const std = @import("std");
const renderer = @import("../renderer.zig");
const terminal = @import("../terminal/main.zig");
/// The messages that can be sent to an IO thread.
pub const IO = union(enum) {
+ pub const SmallWriteArray = [22]u8;
+
/// Resize the window.
resize: struct {
grid_size: renderer.GridSize,
@@ -11,7 +14,19 @@ pub const IO = union(enum) {
/// Clear the selection
clear_selection: void,
- //
- // /// Scroll the viewport
- // scroll_viewport: terminal.Terminal.ScrollViewport,
+
+ /// Scroll the viewport
+ scroll_viewport: terminal.Terminal.ScrollViewport,
+
+ /// Write where the data fits in the union.
+ small_write: struct {
+ data: [22]u8,
+ len: u8,
+ },
};
+
+test {
+ // Ensure we don't grow our IO message size without explicitly wanting to.
+ const testing = std.testing;
+ try testing.expectEqual(@as(usize, 24), @sizeOf(IO));
+}