feat: add registerGlobals
parent
847051ebc3
commit
6559e124a7
|
@ -15,132 +15,18 @@ pub fn main() !void {
|
||||||
// Create an id pool to allocate ids for us
|
// Create an id pool to allocate ids for us
|
||||||
var id_pool = wayland.IdPool{};
|
var id_pool = wayland.IdPool{};
|
||||||
|
|
||||||
// reserve an object id for the registry
|
const ids = try wayland.registerGlobals(gpa, &id_pool, socket, &.{
|
||||||
const registry_id = id_pool.create();
|
wayland.core.Shm,
|
||||||
{
|
wayland.core.Compositor,
|
||||||
var buffer: [5]u32 = undefined;
|
wayland.xdg.WmBase,
|
||||||
const message = try wayland.serialize(wayland.core.Display.Request, &buffer, 1, .{ .get_registry = .{ .registry = registry_id } });
|
wayland.core.Seat,
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
wayland.zxdg.DecorationManagerV1,
|
||||||
}
|
});
|
||||||
|
|
||||||
// create a sync callback so we know when the registry is done listing extensions
|
const shm_id = ids[0] orelse return error.NeccessaryWaylandExtensionMissing;
|
||||||
const registry_done_id = id_pool.create();
|
const compositor_id = ids[1] orelse return error.NeccessaryWaylandExtensionMissing;
|
||||||
std.debug.print("registry done id: {}\n", .{registry_done_id});
|
const xdg_wm_base_id = ids[2] orelse return error.NeccessaryWaylandExtensionMissing;
|
||||||
{
|
const wl_seat_id = ids[3] orelse return error.NeccessaryWaylandExtensionMissing;
|
||||||
var buffer: [5]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(wayland.core.Display.Request, &buffer, 1, .{ .sync = .{ .callback = registry_done_id } });
|
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
var shm_id_opt: ?u32 = null;
|
|
||||||
var compositor_id_opt: ?u32 = null;
|
|
||||||
var xdg_wm_base_id_opt: ?u32 = null;
|
|
||||||
var zxdg_decoration_manager_id_opt: ?u32 = null;
|
|
||||||
var wl_seat_id_opt: ?u32 = null;
|
|
||||||
|
|
||||||
var message_buffer = std.ArrayList(u32).init(gpa);
|
|
||||||
defer message_buffer.deinit();
|
|
||||||
while (true) {
|
|
||||||
var header: wayland.Header = undefined;
|
|
||||||
const header_bytes_read = try socket.readAll(std.mem.asBytes(&header));
|
|
||||||
if (header_bytes_read < @sizeOf(wayland.Header)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
try message_buffer.resize((header.size_and_opcode.size - @sizeOf(wayland.Header)) / @sizeOf(u32));
|
|
||||||
const bytes_read = try socket.readAll(std.mem.sliceAsBytes(message_buffer.items));
|
|
||||||
message_buffer.shrinkRetainingCapacity(bytes_read / @sizeOf(u32));
|
|
||||||
|
|
||||||
if (header.object_id == registry_id) {
|
|
||||||
const event = try wayland.deserialize(wayland.core.Registry.Event, header, message_buffer.items);
|
|
||||||
switch (event) {
|
|
||||||
.global => |global| {
|
|
||||||
var buffer: [20]u32 = undefined;
|
|
||||||
if (std.mem.eql(u8, global.interface, "wl_shm")) {
|
|
||||||
shm_id_opt = id_pool.create();
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Registry.Request,
|
|
||||||
&buffer,
|
|
||||||
registry_id,
|
|
||||||
.{ .bind = .{
|
|
||||||
.name = global.name,
|
|
||||||
.interface = global.interface,
|
|
||||||
.version = global.version,
|
|
||||||
.new_id = shm_id_opt.?,
|
|
||||||
} },
|
|
||||||
);
|
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
} else if (std.mem.eql(u8, global.interface, wayland.core.Compositor.INTERFACE)) {
|
|
||||||
compositor_id_opt = id_pool.create();
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Registry.Request,
|
|
||||||
&buffer,
|
|
||||||
registry_id,
|
|
||||||
.{ .bind = .{
|
|
||||||
.name = global.name,
|
|
||||||
.interface = global.interface,
|
|
||||||
.version = global.version,
|
|
||||||
.new_id = compositor_id_opt.?,
|
|
||||||
} },
|
|
||||||
);
|
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
} else if (std.mem.eql(u8, global.interface, "xdg_wm_base")) {
|
|
||||||
xdg_wm_base_id_opt = id_pool.create();
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Registry.Request,
|
|
||||||
&buffer,
|
|
||||||
registry_id,
|
|
||||||
.{ .bind = .{
|
|
||||||
.name = global.name,
|
|
||||||
.interface = global.interface,
|
|
||||||
.version = global.version,
|
|
||||||
.new_id = xdg_wm_base_id_opt.?,
|
|
||||||
} },
|
|
||||||
);
|
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
} else if (std.mem.eql(u8, global.interface, "zxdg_decoration_manager_v1")) {
|
|
||||||
zxdg_decoration_manager_id_opt = id_pool.create();
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Registry.Request,
|
|
||||||
&buffer,
|
|
||||||
registry_id,
|
|
||||||
.{ .bind = .{
|
|
||||||
.name = global.name,
|
|
||||||
.interface = global.interface,
|
|
||||||
.version = 1,
|
|
||||||
.new_id = zxdg_decoration_manager_id_opt.?,
|
|
||||||
} },
|
|
||||||
);
|
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
} else if (std.mem.eql(u8, global.interface, "wl_seat")) {
|
|
||||||
wl_seat_id_opt = id_pool.create();
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Registry.Request,
|
|
||||||
&buffer,
|
|
||||||
registry_id,
|
|
||||||
.{ .bind = .{
|
|
||||||
.name = global.name,
|
|
||||||
.interface = global.interface,
|
|
||||||
.version = 8,
|
|
||||||
.new_id = wl_seat_id_opt.?,
|
|
||||||
} },
|
|
||||||
);
|
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.global_remove => {},
|
|
||||||
}
|
|
||||||
} else if (header.object_id == registry_done_id) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
std.debug.print("{} {x} \"{}\"\n", .{ header.object_id, header.size_and_opcode.opcode, std.zig.fmtEscapes(std.mem.sliceAsBytes(message_buffer.items)) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const shm_id = shm_id_opt orelse return error.NeccessaryWaylandExtensionMissing;
|
|
||||||
const compositor_id = compositor_id_opt orelse return error.NeccessaryWaylandExtensionMissing;
|
|
||||||
const xdg_wm_base_id = xdg_wm_base_id_opt orelse return error.NeccessaryWaylandExtensionMissing;
|
|
||||||
const wl_seat_id = wl_seat_id_opt orelse return error.NeccessaryWaylandExtensionMissing;
|
|
||||||
|
|
||||||
const surface_id = id_pool.create();
|
const surface_id = id_pool.create();
|
||||||
{
|
{
|
||||||
|
@ -186,7 +72,7 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
var zxdg_toplevel_decoration_id_opt: ?u32 = null;
|
var zxdg_toplevel_decoration_id_opt: ?u32 = null;
|
||||||
if (zxdg_decoration_manager_id_opt) |zxdg_decoration_manager_id| {
|
if (ids[4]) |zxdg_decoration_manager_id| {
|
||||||
zxdg_toplevel_decoration_id_opt = id_pool.create();
|
zxdg_toplevel_decoration_id_opt = id_pool.create();
|
||||||
{
|
{
|
||||||
var buffer: [10]u32 = undefined;
|
var buffer: [10]u32 = undefined;
|
||||||
|
@ -214,12 +100,16 @@ pub fn main() !void {
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
try socket.writeAll(std.mem.sliceAsBytes(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const registry_done_id = id_pool.create();
|
||||||
{
|
{
|
||||||
var buffer: [5]u32 = undefined;
|
var buffer: [5]u32 = undefined;
|
||||||
const message = try wayland.serialize(wayland.core.Display.Request, &buffer, 1, .{ .sync = .{ .callback = registry_done_id } });
|
const message = try wayland.serialize(wayland.core.Display.Request, &buffer, 1, .{ .sync = .{ .callback = registry_done_id } });
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
try socket.writeAll(std.mem.sliceAsBytes(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var message_buffer = std.ArrayList(u32).init(gpa);
|
||||||
|
defer message_buffer.deinit();
|
||||||
|
|
||||||
var done = false;
|
var done = false;
|
||||||
var surface_configured = false;
|
var surface_configured = false;
|
||||||
var seat_capabilties: ?wayland.core.Seat.Capability = null;
|
var seat_capabilties: ?wayland.core.Seat.Capability = null;
|
||||||
|
@ -271,21 +161,6 @@ pub fn main() !void {
|
||||||
const cap: wayland.core.Seat.Capability = @bitCast(capabilities.capability);
|
const cap: wayland.core.Seat.Capability = @bitCast(capabilities.capability);
|
||||||
std.debug.print("<- wl_seat.capabilties = {}\n", .{cap});
|
std.debug.print("<- wl_seat.capabilties = {}\n", .{cap});
|
||||||
seat_capabilties = cap;
|
seat_capabilties = cap;
|
||||||
|
|
||||||
// if (cap.keyboard) {
|
|
||||||
// var buffer: [10]u32 = undefined;
|
|
||||||
// wl_keyboard_id_opt = id_pool.create();
|
|
||||||
// std.debug.print("wl keyboard id: {}\n", .{wl_keyboard_id_opt.?});
|
|
||||||
// const message = try wayland.serialize(
|
|
||||||
// wayland.core.Seat.Request,
|
|
||||||
// &buffer,
|
|
||||||
// wl_seat_id,
|
|
||||||
// .{ .get_keyboard = .{
|
|
||||||
// .new_id = wl_keyboard_id_opt.?,
|
|
||||||
// } },
|
|
||||||
// );
|
|
||||||
// try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
.name => |name| {
|
.name => |name| {
|
||||||
std.debug.print("<- wl_seat.name = {s}\n", .{name.name});
|
std.debug.print("<- wl_seat.name = {s}\n", .{name.name});
|
||||||
|
|
|
@ -53,6 +53,7 @@ pub const Registry = struct {
|
||||||
|
|
||||||
pub const Compositor = struct {
|
pub const Compositor = struct {
|
||||||
pub const INTERFACE = "wl_compositor";
|
pub const INTERFACE = "wl_compositor";
|
||||||
|
pub const VERSION = 5;
|
||||||
|
|
||||||
pub const Request = union(enum) {
|
pub const Request = union(enum) {
|
||||||
create_surface: struct {
|
create_surface: struct {
|
||||||
|
@ -82,6 +83,9 @@ pub const ShmPool = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Shm = struct {
|
pub const Shm = struct {
|
||||||
|
pub const INTERFACE = "wl_shm";
|
||||||
|
pub const VERSION = 1;
|
||||||
|
|
||||||
pub const Request = union(enum) {
|
pub const Request = union(enum) {
|
||||||
create_pool: struct {
|
create_pool: struct {
|
||||||
new_id: u32,
|
new_id: u32,
|
||||||
|
@ -172,6 +176,9 @@ pub const Buffer = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Seat = struct {
|
pub const Seat = struct {
|
||||||
|
pub const INTERFACE = "wl_seat";
|
||||||
|
pub const VERSION = 8;
|
||||||
|
|
||||||
pub const Request = union(enum) {
|
pub const Request = union(enum) {
|
||||||
get_pointer: struct {
|
get_pointer: struct {
|
||||||
new_id: u32,
|
new_id: u32,
|
||||||
|
|
66
src/main.zig
66
src/main.zig
|
@ -347,3 +347,69 @@ pub const IdPool = struct {
|
||||||
this.free_ids.append(id) catch {};
|
this.free_ids.append(id) catch {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn registerGlobals(alloc: std.mem.Allocator, id_pool: *IdPool, socket: std.net.Stream, comptime T: []const type) ![T.len]?u32 {
|
||||||
|
const Item = struct { version: u32, index: u32 };
|
||||||
|
const Pair = struct { []const u8, Item };
|
||||||
|
comptime var kvs_list: []const Pair = &[_]Pair{};
|
||||||
|
inline for (T, 0..) |t, i| {
|
||||||
|
// if (!@hasField(t, "INTERFACE")) @compileError("Missing INTERFACE for " ++ @typeName(t));
|
||||||
|
// if (!@hasField(t, "VERSION")) @compileError("Missing VERSION for " ++ @typeName(t));
|
||||||
|
kvs_list = kvs_list ++ &[_]Pair{.{ t.INTERFACE, .{ .version = t.VERSION, .index = i } }};
|
||||||
|
}
|
||||||
|
const map = std.ComptimeStringMap(Item, kvs_list);
|
||||||
|
|
||||||
|
const registry_id = id_pool.create();
|
||||||
|
{
|
||||||
|
var buffer: [5]u32 = undefined;
|
||||||
|
const message = try serialize(core.Display.Request, &buffer, 1, .{ .get_registry = .{ .registry = registry_id } });
|
||||||
|
try socket.writeAll(std.mem.sliceAsBytes(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
const registry_done_id = id_pool.create();
|
||||||
|
{
|
||||||
|
var buffer: [5]u32 = undefined;
|
||||||
|
const message = try serialize(core.Display.Request, &buffer, 1, .{ .sync = .{ .callback = registry_done_id } });
|
||||||
|
try socket.writeAll(std.mem.sliceAsBytes(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids: [T.len]?u32 = [_]?u32{null} ** T.len;
|
||||||
|
var message_buffer = std.ArrayList(u32).init(alloc);
|
||||||
|
defer message_buffer.deinit();
|
||||||
|
while (true) {
|
||||||
|
var header: Header = undefined;
|
||||||
|
const header_bytes_read = try socket.readAll(std.mem.asBytes(&header));
|
||||||
|
if (header_bytes_read < @sizeOf(Header)) break;
|
||||||
|
|
||||||
|
try message_buffer.resize((header.size_and_opcode.size - @sizeOf(Header)) / @sizeOf(u32));
|
||||||
|
const bytes_read = try socket.readAll(std.mem.sliceAsBytes(message_buffer.items));
|
||||||
|
message_buffer.shrinkRetainingCapacity(bytes_read / @sizeOf(u32));
|
||||||
|
|
||||||
|
if (header.object_id == registry_id) {
|
||||||
|
const event = try deserialize(core.Registry.Event, header, message_buffer.items);
|
||||||
|
switch (event) {
|
||||||
|
.global => |global| {
|
||||||
|
var buffer: [20]u32 = undefined;
|
||||||
|
if (map.get(global.interface)) |item| {
|
||||||
|
const new_id = id_pool.create();
|
||||||
|
ids[item.index] = new_id;
|
||||||
|
const message = try serialize(core.Registry.Request, &buffer, registry_id, .{ .bind = .{
|
||||||
|
.name = global.name,
|
||||||
|
.interface = global.interface,
|
||||||
|
.version = item.version,
|
||||||
|
.new_id = new_id,
|
||||||
|
} });
|
||||||
|
try socket.writeAll(std.mem.sliceAsBytes(message));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.global_remove => {},
|
||||||
|
}
|
||||||
|
} else if (header.object_id == registry_done_id) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
std.log.info("{} {x} \"{}\"", .{ header.object_id, header.size_and_opcode.opcode, std.zig.fmtEscapes(std.mem.sliceAsBytes(message_buffer.items)) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
pub const WmBase = struct {
|
pub const WmBase = struct {
|
||||||
|
pub const INTERFACE = "xdg_wm_base";
|
||||||
|
pub const VERSION = 4;
|
||||||
|
|
||||||
pub const Request = union(Request.Tag) {
|
pub const Request = union(Request.Tag) {
|
||||||
destroy: void,
|
destroy: void,
|
||||||
create_positioner: struct {
|
create_positioner: struct {
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
pub const DecorationManagerV1 = struct {
|
pub const DecorationManagerV1 = struct {
|
||||||
|
pub const INTERFACE = "zxdg_decoration_manager_v1";
|
||||||
|
pub const VERSION = 1;
|
||||||
|
|
||||||
pub const Request = union(Request.Tag) {
|
pub const Request = union(Request.Tag) {
|
||||||
destroy: void,
|
destroy: void,
|
||||||
get_toplevel_decoration: struct {
|
get_toplevel_decoration: struct {
|
||||||
|
|
Loading…
Reference in New Issue