This repository has been archived by the owner on Jan 8, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhello.zig
109 lines (90 loc) · 3.39 KB
/
hello.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const std = @import("std");
const mem = std.mem;
const posix = std.posix;
const wayland = @import("wayland");
const wl = wayland.client.wl;
const xdg = wayland.client.xdg;
const Context = struct {
shm: ?*wl.Shm,
compositor: ?*wl.Compositor,
wm_base: ?*xdg.WmBase,
};
pub fn main() anyerror!void {
const display = try wl.Display.connect(null);
const registry = try display.getRegistry();
var context = Context{
.shm = null,
.compositor = null,
.wm_base = null,
};
registry.setListener(*Context, registryListener, &context);
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
const shm = context.shm orelse return error.NoWlShm;
const compositor = context.compositor orelse return error.NoWlCompositor;
const wm_base = context.wm_base orelse return error.NoXdgWmBase;
const buffer = blk: {
const width = 128;
const height = 128;
const stride = width * 4;
const size = stride * height;
const fd = try posix.memfd_create("hello-zig-wayland", 0);
try posix.ftruncate(fd, size);
const data = try posix.mmap(
null,
size,
posix.PROT.READ | posix.PROT.WRITE,
.{ .TYPE = .SHARED },
fd,
0,
);
@memcpy(data, @embedFile("cat.bgra"));
const pool = try shm.createPool(fd, size);
defer pool.destroy();
break :blk try pool.createBuffer(0, width, height, stride, wl.Shm.Format.argb8888);
};
defer buffer.destroy();
const surface = try compositor.createSurface();
defer surface.destroy();
const xdg_surface = try wm_base.getXdgSurface(surface);
defer xdg_surface.destroy();
const xdg_toplevel = try xdg_surface.getToplevel();
defer xdg_toplevel.destroy();
var running = true;
xdg_surface.setListener(*wl.Surface, xdgSurfaceListener, surface);
xdg_toplevel.setListener(*bool, xdgToplevelListener, &running);
surface.commit();
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
surface.attach(buffer, 0, 0);
surface.commit();
while (running) {
if (display.dispatch() != .SUCCESS) return error.DispatchFailed;
}
}
fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, context: *Context) void {
switch (event) {
.global => |global| {
if (mem.orderZ(u8, global.interface, wl.Compositor.getInterface().name) == .eq) {
context.compositor = registry.bind(global.name, wl.Compositor, 1) catch return;
} else if (mem.orderZ(u8, global.interface, wl.Shm.getInterface().name) == .eq) {
context.shm = registry.bind(global.name, wl.Shm, 1) catch return;
} else if (mem.orderZ(u8, global.interface, xdg.WmBase.getInterface().name) == .eq) {
context.wm_base = registry.bind(global.name, xdg.WmBase, 1) catch return;
}
},
.global_remove => {},
}
}
fn xdgSurfaceListener(xdg_surface: *xdg.Surface, event: xdg.Surface.Event, surface: *wl.Surface) void {
switch (event) {
.configure => |configure| {
xdg_surface.ackConfigure(configure.serial);
surface.commit();
},
}
}
fn xdgToplevelListener(_: *xdg.Toplevel, event: xdg.Toplevel.Event, running: *bool) void {
switch (event) {
.configure => {},
.close => running.* = false,
}
}