mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
rename termio thread message struct
This commit is contained in:
@ -611,7 +611,7 @@ fn charCallback(window: glfw.Window, codepoint: u21) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ask our IO thread to write the data
|
// Ask our IO thread to write the data
|
||||||
var data: termio.message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
data[0] = @intCast(u8, codepoint);
|
data[0] = @intCast(u8, codepoint);
|
||||||
_ = win.io_thread.mailbox.push(.{
|
_ = win.io_thread.mailbox.push(.{
|
||||||
.write_small = .{
|
.write_small = .{
|
||||||
@ -771,7 +771,7 @@ fn keyCallback(
|
|||||||
}, .{ .forever = {} });
|
}, .{ .forever = {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = win.io_thread.mailbox.push(termio.message.IO.writeReq(
|
_ = win.io_thread.mailbox.push(termio.Message.writeReq(
|
||||||
win.alloc,
|
win.alloc,
|
||||||
data,
|
data,
|
||||||
) catch unreachable, .{ .forever = {} });
|
) catch unreachable, .{ .forever = {} });
|
||||||
@ -851,7 +851,7 @@ fn keyCallback(
|
|||||||
};
|
};
|
||||||
if (char > 0) {
|
if (char > 0) {
|
||||||
// Ask our IO thread to write the data
|
// Ask our IO thread to write the data
|
||||||
var data: termio.message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
data[0] = @intCast(u8, char);
|
data[0] = @intCast(u8, char);
|
||||||
_ = win.io_thread.mailbox.push(.{
|
_ = win.io_thread.mailbox.push(.{
|
||||||
.write_small = .{
|
.write_small = .{
|
||||||
@ -1037,7 +1037,7 @@ fn mouseReport(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// + 1 below is because our x/y is 0-indexed and proto wants 1
|
// + 1 below is because our x/y is 0-indexed and proto wants 1
|
||||||
var data: termio.message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
assert(data.len >= 5);
|
assert(data.len >= 5);
|
||||||
data[0] = '\x1b';
|
data[0] = '\x1b';
|
||||||
data[1] = '[';
|
data[1] = '[';
|
||||||
@ -1057,7 +1057,7 @@ fn mouseReport(
|
|||||||
|
|
||||||
.utf8 => {
|
.utf8 => {
|
||||||
// Maximum of 12 because at most we have 2 fully UTF-8 encoded chars
|
// Maximum of 12 because at most we have 2 fully UTF-8 encoded chars
|
||||||
var data: termio.message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
assert(data.len >= 12);
|
assert(data.len >= 12);
|
||||||
data[0] = '\x1b';
|
data[0] = '\x1b';
|
||||||
data[1] = '[';
|
data[1] = '[';
|
||||||
@ -1086,7 +1086,7 @@ fn mouseReport(
|
|||||||
|
|
||||||
// Response always is at least 4 chars, so this leaves the
|
// Response always is at least 4 chars, so this leaves the
|
||||||
// remainder for numbers which are very large...
|
// remainder for numbers which are very large...
|
||||||
var data: termio.message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
const resp = try std.fmt.bufPrint(&data, "\x1B[<{d};{d};{d}{c}", .{
|
const resp = try std.fmt.bufPrint(&data, "\x1B[<{d};{d};{d}{c}", .{
|
||||||
button_code,
|
button_code,
|
||||||
viewport_point.x + 1,
|
viewport_point.x + 1,
|
||||||
@ -1106,7 +1106,7 @@ fn mouseReport(
|
|||||||
.urxvt => {
|
.urxvt => {
|
||||||
// Response always is at least 4 chars, so this leaves the
|
// Response always is at least 4 chars, so this leaves the
|
||||||
// remainder for numbers which are very large...
|
// remainder for numbers which are very large...
|
||||||
var data: termio.message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
const resp = try std.fmt.bufPrint(&data, "\x1B[{d};{d};{d}M", .{
|
const resp = try std.fmt.bufPrint(&data, "\x1B[{d};{d};{d}M", .{
|
||||||
32 + button_code,
|
32 + button_code,
|
||||||
viewport_point.x + 1,
|
viewport_point.x + 1,
|
||||||
@ -1128,7 +1128,7 @@ fn mouseReport(
|
|||||||
|
|
||||||
// Response always is at least 4 chars, so this leaves the
|
// Response always is at least 4 chars, so this leaves the
|
||||||
// remainder for numbers which are very large...
|
// remainder for numbers which are very large...
|
||||||
var data: termio.message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
const resp = try std.fmt.bufPrint(&data, "\x1B[<{d};{d};{d}{c}", .{
|
const resp = try std.fmt.bufPrint(&data, "\x1B[<{d};{d};{d}{c}", .{
|
||||||
button_code,
|
button_code,
|
||||||
pos.xpos,
|
pos.xpos,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//! for taking the config, spinning up a child process, and handling IO
|
//! for taking the config, spinning up a child process, and handling IO
|
||||||
//! with the termianl.
|
//! with the termianl.
|
||||||
|
|
||||||
pub const message = @import("termio/message.zig");
|
pub usingnamespace @import("termio/message.zig");
|
||||||
pub const Exec = @import("termio/Exec.zig");
|
pub const Exec = @import("termio/Exec.zig");
|
||||||
pub const Options = @import("termio/Options.zig");
|
pub const Options = @import("termio/Options.zig");
|
||||||
pub const Thread = @import("termio/Thread.zig");
|
pub const Thread = @import("termio/Thread.zig");
|
||||||
|
@ -14,7 +14,7 @@ const log = std.log.scoped(.io_thread);
|
|||||||
/// The type used for sending messages to the IO thread. For now this is
|
/// The type used for sending messages to the IO thread. For now this is
|
||||||
/// hardcoded with a capacity. We can make this a comptime parameter in
|
/// hardcoded with a capacity. We can make this a comptime parameter in
|
||||||
/// the future if we want it configurable.
|
/// the future if we want it configurable.
|
||||||
const Mailbox = BlockingQueue(termio.message.IO, 64);
|
const Mailbox = BlockingQueue(termio.Message, 64);
|
||||||
|
|
||||||
/// The main event loop for the thread. The user data of this loop
|
/// The main event loop for the thread. The user data of this loop
|
||||||
/// is always the allocator used to create the loop. This is a convenience
|
/// is always the allocator used to create the loop. This is a convenience
|
||||||
|
@ -9,7 +9,7 @@ const terminal = @import("../terminal/main.zig");
|
|||||||
/// This is not a tiny structure (~40 bytes at the time of writing this comment),
|
/// This is not a tiny structure (~40 bytes at the time of writing this comment),
|
||||||
/// but the messages are IO thread sends are also very few. At the current size
|
/// but the messages are IO thread sends are also very few. At the current size
|
||||||
/// we can queue 26,000 messages before consuming a MB of RAM.
|
/// we can queue 26,000 messages before consuming a MB of RAM.
|
||||||
pub const IO = union(enum) {
|
pub const Message = union(enum) {
|
||||||
/// Resize the window.
|
/// Resize the window.
|
||||||
resize: struct {
|
resize: struct {
|
||||||
grid_size: renderer.GridSize,
|
grid_size: renderer.GridSize,
|
||||||
@ -28,7 +28,7 @@ pub const IO = union(enum) {
|
|||||||
/// Return a write request for the given data. This will use
|
/// Return a write request for the given data. This will use
|
||||||
/// write_small if it fits or write_alloc otherwise. This should NOT
|
/// write_small if it fits or write_alloc otherwise. This should NOT
|
||||||
/// be used for stable pointers which can be manually set to write_stable.
|
/// be used for stable pointers which can be manually set to write_stable.
|
||||||
pub fn writeReq(alloc: Allocator, data: anytype) !IO {
|
pub fn writeReq(alloc: Allocator, data: anytype) !Message {
|
||||||
switch (@typeInfo(@TypeOf(data))) {
|
switch (@typeInfo(@TypeOf(data))) {
|
||||||
.Pointer => |info| {
|
.Pointer => |info| {
|
||||||
assert(info.size == .Slice);
|
assert(info.size == .Slice);
|
||||||
@ -38,7 +38,7 @@ pub const IO = union(enum) {
|
|||||||
if (data.len <= WriteReq.Small.Max) {
|
if (data.len <= WriteReq.Small.Max) {
|
||||||
var buf: WriteReq.Small.Array = undefined;
|
var buf: WriteReq.Small.Array = undefined;
|
||||||
std.mem.copy(u8, &buf, data);
|
std.mem.copy(u8, &buf, data);
|
||||||
return IO{
|
return Message{
|
||||||
.write_small = .{
|
.write_small = .{
|
||||||
.data = buf,
|
.data = buf,
|
||||||
.len = @intCast(u8, data.len),
|
.len = @intCast(u8, data.len),
|
||||||
@ -49,7 +49,7 @@ pub const IO = union(enum) {
|
|||||||
// Otherwise, allocate
|
// Otherwise, allocate
|
||||||
var buf = try alloc.dupe(u8, data);
|
var buf = try alloc.dupe(u8, data);
|
||||||
errdefer alloc.free(buf);
|
errdefer alloc.free(buf);
|
||||||
return IO{
|
return Message{
|
||||||
.write_alloc = .{
|
.write_alloc = .{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.data = buf,
|
.data = buf,
|
||||||
@ -60,32 +60,32 @@ pub const IO = union(enum) {
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/// Represents a write request.
|
/// Represents a write request.
|
||||||
pub const WriteReq = union(enum) {
|
pub const WriteReq = union(enum) {
|
||||||
pub const Small = struct {
|
pub const Small = struct {
|
||||||
pub const Max = 38;
|
pub const Max = 38;
|
||||||
pub const Array = [Max]u8;
|
pub const Array = [Max]u8;
|
||||||
data: Array,
|
data: Array,
|
||||||
len: u8,
|
len: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Alloc = struct {
|
||||||
|
alloc: Allocator,
|
||||||
|
data: []u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A small write where the data fits into this union size.
|
||||||
|
small: Small,
|
||||||
|
|
||||||
|
/// A stable pointer so we can just pass the slice directly through.
|
||||||
|
/// This is useful i.e. for const data.
|
||||||
|
stable: []const u8,
|
||||||
|
|
||||||
|
/// Allocated and must be freed with the provided allocator. This
|
||||||
|
/// should be rarely used.
|
||||||
|
alloc: Alloc,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Alloc = struct {
|
|
||||||
alloc: Allocator,
|
|
||||||
data: []u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A small write where the data fits into this union size.
|
|
||||||
small: Small,
|
|
||||||
|
|
||||||
/// A stable pointer so we can just pass the slice directly through.
|
|
||||||
/// This is useful i.e. for const data.
|
|
||||||
stable: []const u8,
|
|
||||||
|
|
||||||
/// Allocated and must be freed with the provided allocator. This
|
|
||||||
/// should be rarely used.
|
|
||||||
alloc: Alloc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
test {
|
test {
|
||||||
@ -95,24 +95,24 @@ test {
|
|||||||
test {
|
test {
|
||||||
// Ensure we don't grow our IO message size without explicitly wanting to.
|
// Ensure we don't grow our IO message size without explicitly wanting to.
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
try testing.expectEqual(@as(usize, 40), @sizeOf(IO));
|
try testing.expectEqual(@as(usize, 40), @sizeOf(Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "IO.writeReq small" {
|
test "Message.writeReq small" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
const input = "hello!";
|
const input = "hello!";
|
||||||
const io = try IO.writeReq(alloc, @as([]const u8, input));
|
const io = try Message.writeReq(alloc, @as([]const u8, input));
|
||||||
try testing.expect(io == .write_small);
|
try testing.expect(io == .write_small);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "IO.writeReq alloc" {
|
test "Message.writeReq alloc" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
const input = "hello! " ** 100;
|
const input = "hello! " ** 100;
|
||||||
const io = try IO.writeReq(alloc, @as([]const u8, input));
|
const io = try Message.writeReq(alloc, @as([]const u8, input));
|
||||||
try testing.expect(io == .write_alloc);
|
try testing.expect(io == .write_alloc);
|
||||||
io.write_alloc.alloc.free(io.write_alloc.data);
|
io.write_alloc.alloc.free(io.write_alloc.data);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user