aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/pkg/macos/foundation/dictionary.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/pkg/macos/foundation/dictionary.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/pkg/macos/foundation/dictionary.zig')
-rw-r--r--vendor/libghostty-vt/pkg/macos/foundation/dictionary.zig125
1 files changed, 125 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/pkg/macos/foundation/dictionary.zig b/vendor/libghostty-vt/pkg/macos/foundation/dictionary.zig
new file mode 100644
index 00000000..a529442a
--- /dev/null
+++ b/vendor/libghostty-vt/pkg/macos/foundation/dictionary.zig
@@ -0,0 +1,125 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const Allocator = std.mem.Allocator;
+const foundation = @import("../foundation.zig");
+const c = @import("c.zig").c;
+
+pub const Dictionary = opaque {
+ pub fn create(
+ keys: ?[]const ?*const anyopaque,
+ values: ?[]const ?*const anyopaque,
+ ) Allocator.Error!*Dictionary {
+ if (keys != null or values != null) {
+ assert(keys != null);
+ assert(values != null);
+ assert(keys.?.len == values.?.len);
+ }
+
+ return @as(?*Dictionary, @ptrFromInt(@intFromPtr(c.CFDictionaryCreate(
+ null,
+ @ptrCast(@constCast(if (keys) |slice| slice.ptr else null)),
+ @ptrCast(@constCast(if (values) |slice| slice.ptr else null)),
+ @intCast(if (keys) |slice| slice.len else 0),
+ &c.kCFTypeDictionaryKeyCallBacks,
+ &c.kCFTypeDictionaryValueCallBacks,
+ )))) orelse Allocator.Error.OutOfMemory;
+ }
+
+ pub fn release(self: *Dictionary) void {
+ foundation.CFRelease(self);
+ }
+
+ pub fn getCount(self: *Dictionary) usize {
+ return @intCast(c.CFDictionaryGetCount(@ptrCast(self)));
+ }
+
+ pub fn getValue(self: *Dictionary, comptime V: type, key: ?*const anyopaque) ?*V {
+ return @ptrFromInt(@intFromPtr(c.CFDictionaryGetValue(
+ @ptrCast(self),
+ key,
+ )));
+ }
+
+ pub fn getKeysAndValues(self: *Dictionary, alloc: Allocator) !struct {
+ keys: []?*const anyopaque,
+ values: []?*const anyopaque,
+ } {
+ const count = self.getCount();
+ const keys = try alloc.alloc(?*const anyopaque, count);
+ errdefer alloc.free(keys);
+ const values = try alloc.alloc(?*const anyopaque, count);
+ errdefer alloc.free(values);
+ c.CFDictionaryGetKeysAndValues(
+ @ptrCast(self),
+ @ptrCast(keys.ptr),
+ @ptrCast(values.ptr),
+ );
+ return .{ .keys = keys, .values = values };
+ }
+};
+
+pub const MutableDictionary = opaque {
+ pub fn create(cap: usize) Allocator.Error!*MutableDictionary {
+ return @as(?*MutableDictionary, @ptrFromInt(@intFromPtr(c.CFDictionaryCreateMutable(
+ null,
+ @intCast(cap),
+ &c.kCFTypeDictionaryKeyCallBacks,
+ &c.kCFTypeDictionaryValueCallBacks,
+ )))) orelse Allocator.Error.OutOfMemory;
+ }
+
+ pub fn createMutableCopy(cap: usize, src: *Dictionary) Allocator.Error!*MutableDictionary {
+ return @as(?*MutableDictionary, @ptrFromInt(@intFromPtr(c.CFDictionaryCreateMutableCopy(
+ null,
+ @intCast(cap),
+ @ptrCast(src),
+ )))) orelse Allocator.Error.OutOfMemory;
+ }
+
+ pub fn release(self: *MutableDictionary) void {
+ foundation.CFRelease(self);
+ }
+
+ pub fn setValue(self: *MutableDictionary, key: ?*const anyopaque, value: ?*const anyopaque) void {
+ c.CFDictionarySetValue(
+ @ptrCast(self),
+ key,
+ value,
+ );
+ }
+};
+
+test "dictionary" {
+ const testing = std.testing;
+
+ const str = try foundation.String.createWithBytes("hello", .unicode, false);
+ defer str.release();
+
+ var keys = [_]?*const anyopaque{c.kCFURLIsPurgeableKey};
+ var values = [_]?*const anyopaque{str};
+ const dict = try Dictionary.create(&keys, &values);
+ defer dict.release();
+
+ try testing.expectEqual(@as(usize, 1), dict.getCount());
+ try testing.expect(dict.getValue(foundation.String, c.kCFURLIsPurgeableKey) != null);
+ try testing.expect(dict.getValue(foundation.String, c.kCFURLIsVolumeKey) == null);
+}
+
+test "mutable dictionary" {
+ const testing = std.testing;
+
+ const dict = try MutableDictionary.create(0);
+ defer dict.release();
+
+ const str = try foundation.String.createWithBytes("hello", .unicode, false);
+ defer str.release();
+
+ dict.setValue(c.kCFURLIsPurgeableKey, str);
+
+ {
+ const imm = @as(*Dictionary, @ptrCast(dict));
+ try testing.expectEqual(@as(usize, 1), imm.getCount());
+ try testing.expect(imm.getValue(foundation.String, c.kCFURLIsPurgeableKey) != null);
+ try testing.expect(imm.getValue(foundation.String, c.kCFURLIsVolumeKey) == null);
+ }
+}