lib/sys/src/x11/xlib.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 
 3 const sys = @import("../root.zig");
 4 const display_mod = @import("display.zig");
 5 
 6 pub const Error = error{
 7     RuntimeUnavailable,
 8     SymbolMissing,
 9     InvalidDisplay,
10 };
11 
12 pub const Display = opaque {};
13 
14 const XOpenDisplayFn = *const fn (display_name: ?[*:0]const u8) callconv(.c) ?*Display;
15 const XCloseDisplayFn = *const fn (display: *Display) callconv(.c) c_int;
16 
17 pub const Connection = struct {
18     library: sys.dynamic.Library,
19     display: *Display,
20     close_fn: XCloseDisplayFn,
21 
22     pub fn close(self: *Connection) void {
23         _ = self.close_fn(self.display);
24         self.library.close();
25         self.* = undefined;
26     }
27 };
28 
29 pub fn openTarget(target: display_mod.Target) Error!Connection {
30     var name_buffer: [32]u8 = undefined;
31     const name = std.fmt.bufPrintSentinel(&name_buffer, ":{d}.{d}", .{ target.display, target.screen }, 0) catch return error.InvalidDisplay;
32     return openName(name);
33 }
34 
35 pub fn openDefault() Error!Connection {
36     return openName(null);
37 }
38 
39 fn openName(name: ?[:0]const u8) Error!Connection {
40     var library = sys.dynamic.openX11Library() catch return error.RuntimeUnavailable;
41     errdefer library.close();
42 
43     const open_fn = library.lookup(XOpenDisplayFn, "XOpenDisplay") orelse return error.SymbolMissing;
44     const close_fn = library.lookup(XCloseDisplayFn, "XCloseDisplay") orelse return error.SymbolMissing;
45     const display = open_fn(if (name) |actual| actual.ptr else null) orelse return error.RuntimeUnavailable;
46     return .{
47         .library = library,
48         .display = display,
49         .close_fn = close_fn,
50     };
51 }
52 
53 test "xlib dynamic candidate list is host-scoped" {
54     const candidates = sys.dynamic.x11LibraryCandidates();
55     try std.testing.expect(candidates.len >= 1);
56     if (comptime @import("builtin").os.tag == .linux) {
57         try std.testing.expect(sys.dynamic.hasHostCandidate(candidates));
58     }
59 }