mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
kitty graphics: add support for shared memory transfer medium
Adds support for using shared memory to transfer images between the CLI and Ghostty using the Kitty image protocol. This should be the fastest way to transfer images if the CLI program and Ghostty are running on the same system. Works for single image transfer using `kitten icat`: ``` kitten icat --transfer-mode=memory images/icons/icon_256x256.png ``` However trying to play a movie with `mpv` fails in Ghostty (although it works in Kitty): ``` mpv --vo=kitty --vo-kitty-use-shm=yes --profile=sw-fast --really-quiet video.mp4 ``` `mpv` appears to be sending frames using the normal image transfer commands but always setting `more_chunks` to `true` which results in an image never being shown by Ghostty. Shared memory transfer on Windows remains to be implemented.
This commit is contained in:
@ -75,9 +75,13 @@ pub const LoadingImage = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var abs_buf: [std.fs.max_path_bytes]u8 = undefined;
|
var abs_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
const path = posix.realpath(cmd.data, &abs_buf) catch |err| {
|
const path = switch (t.medium) {
|
||||||
log.warn("failed to get absolute path: {}", .{err});
|
.direct => unreachable, // handled above
|
||||||
return error.InvalidData;
|
.file, .temporary_file => posix.realpath(cmd.data, &abs_buf) catch |err| {
|
||||||
|
log.warn("failed to get absolute path: {}", .{err});
|
||||||
|
return error.InvalidData;
|
||||||
|
},
|
||||||
|
.shared_memory => cmd.data,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Depending on the medium, load the data from the path.
|
// Depending on the medium, load the data from the path.
|
||||||
@ -98,15 +102,53 @@ pub const LoadingImage = struct {
|
|||||||
t: command.Transmission,
|
t: command.Transmission,
|
||||||
path: []const u8,
|
path: []const u8,
|
||||||
) !void {
|
) !void {
|
||||||
// We require libc for this for shm_open
|
switch (builtin.target.os.tag) {
|
||||||
if (comptime !builtin.link_libc) return error.UnsupportedMedium;
|
.windows => {
|
||||||
|
// TODO: support shared memory on windows
|
||||||
|
return error.UnsupportedMedium;
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
// libc is required for shm_open
|
||||||
|
if (comptime !builtin.link_libc) return error.UnsupportedMedium;
|
||||||
|
|
||||||
// Todo: support shared memory
|
const pathz = try alloc.dupeZ(u8, path);
|
||||||
_ = self;
|
defer alloc.free(pathz);
|
||||||
_ = alloc;
|
|
||||||
_ = t;
|
const fd = std.c.shm_open(pathz, @as(c_int, @bitCast(std.c.O{ .ACCMODE = .RDONLY })), 0);
|
||||||
_ = path;
|
switch (std.posix.errno(fd)) {
|
||||||
return error.UnsupportedMedium;
|
.SUCCESS => {
|
||||||
|
defer _ = std.c.close(fd);
|
||||||
|
defer _ = std.c.shm_unlink(pathz);
|
||||||
|
|
||||||
|
const stat = std.posix.fstat(fd) catch |err| {
|
||||||
|
log.warn("unable to fstat shared memory {s}: {}", .{ path, err });
|
||||||
|
return error.InvalidData;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (stat.size <= 0) return error.InvalidData;
|
||||||
|
|
||||||
|
const size: usize = @intCast(stat.size);
|
||||||
|
|
||||||
|
const map = std.posix.mmap(null, size, std.c.PROT.READ, std.c.MAP{ .TYPE = .SHARED }, fd, 0) catch |err| {
|
||||||
|
log.warn("unable to mmap shared memory {s}: {}", .{ path, err });
|
||||||
|
return error.InvalidData;
|
||||||
|
};
|
||||||
|
defer std.posix.munmap(map);
|
||||||
|
|
||||||
|
const start: usize = @intCast(t.offset);
|
||||||
|
const end: usize = if (t.size > 0) @min(@as(usize, @intCast(t.offset)) + @as(usize, @intCast(t.size)), size) else size;
|
||||||
|
|
||||||
|
assert(self.data.items.len == 0);
|
||||||
|
try self.data.appendSlice(alloc, map[start..end]);
|
||||||
|
},
|
||||||
|
|
||||||
|
else => |err| {
|
||||||
|
log.warn("unable to open shared memory {s}: {}", .{ path, err });
|
||||||
|
return error.InvalidData;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the data from a temporary file and returns it. This allocates
|
/// Reads the data from a temporary file and returns it. This allocates
|
||||||
|
Reference in New Issue
Block a user