lib/wayland/src/protocol/bootstrap/display.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const protocol = @import("../root.zig");
2
3 const core = protocol.core.wl_display;
4
5 pub const Sync = struct {
6 callback: protocol.value.NewId,
7
8 pub fn encode(self: Sync, encoder: *protocol.value.Encoder) !protocol.value.Encoded {
9 encoder.reset();
10 errdefer encoder.reset();
11 try encoder.newId(self.callback);
12 return encoder.finish(&core.requests.sync);
13 }
14 };
15
16 pub const GetRegistry = struct {
17 registry: protocol.value.NewId,
18
19 pub fn encode(self: GetRegistry, encoder: *protocol.value.Encoder) !protocol.value.Encoded {
20 encoder.reset();
21 errdefer encoder.reset();
22 try encoder.newId(self.registry);
23 return encoder.finish(&core.requests.get_registry);
24 }
25 };
26
27 pub const Fatal = struct {
28 object_id: protocol.value.ObjectId,
29 code: u32,
30 message: []const u8,
31 };
32
33 pub const DeleteId = struct {
34 id: u32,
35 };
36
37 pub const Event = union(enum) {
38 fatal: Fatal,
39 delete_id: DeleteId,
40 };
41
42 pub fn decodeEvent(
43 opcode: u16,
44 payload: []const u8,
45 descriptors: []const @import("sys").fd.Descriptor,
46 ) !Event {
47 const metadata = core.metadata.event(opcode) orelse return error.UnknownOpcode;
48 var decoder = try protocol.value.Decoder.init(metadata, payload, descriptors);
49 const event: Event = switch (opcode) {
50 core.events.@"error".opcode => .{ .fatal = .{
51 .object_id = try decoder.object(),
52 .code = try decoder.unsigned(),
53 .message = try decoder.string(),
54 } },
55 core.events.delete_id.opcode => .{ .delete_id = .{
56 .id = try decoder.unsigned(),
57 } },
58 else => unreachable,
59 };
60 try decoder.finish();
61 return event;
62 }
63
64 test "display bootstrap requests use generated opcodes" {
65 const std = @import("std");
66
67 var encoder = try protocol.value.Encoder.init(
68 std.testing.allocator,
69 protocol.value.default_encoder_capacity,
70 );
71 defer encoder.deinit();
72 const callback = try (Sync{ .callback = try .init(2) }).encode(&encoder);
73 try std.testing.expectEqual(@as(u16, 0), callback.opcode());
74 try std.testing.expectEqualSlices(u8, &.{ 2, 0, 0, 0 }, callback.payload);
75 const registry = try (GetRegistry{ .registry = try .init(3) }).encode(&encoder);
76 try std.testing.expectEqual(@as(u16, 1), registry.opcode());
77 try std.testing.expectEqualSlices(u8, &.{ 3, 0, 0, 0 }, registry.payload);
78 }
79
80 test "display events reject malformed payloads" {
81 const std = @import("std");
82
83 const delete_payload = [_]u8{ 9, 0, 0, 0 };
84 const event = try decodeEvent(core.events.delete_id.opcode, &delete_payload, &.{});
85 try std.testing.expectEqual(@as(u32, 9), event.delete_id.id);
86 try std.testing.expectError(error.UnknownOpcode, decodeEvent(9, &.{}, &.{}));
87 try std.testing.expectError(
88 error.PayloadTooSmall,
89 decodeEvent(core.events.@"error".opcode, &delete_payload, &.{}),
90 );
91 }