feat: add wayland.Conn
parent
6559e124a7
commit
ea4a75cc76
|
@ -9,13 +9,13 @@ pub fn main() !void {
|
||||||
const display_path = try wayland.getDisplayPath(gpa);
|
const display_path = try wayland.getDisplayPath(gpa);
|
||||||
defer gpa.free(display_path);
|
defer gpa.free(display_path);
|
||||||
|
|
||||||
const socket = try std.net.connectUnixSocket(display_path);
|
var conn = try wayland.Conn.init(gpa, display_path);
|
||||||
defer socket.close();
|
defer conn.deinit();
|
||||||
|
|
||||||
// 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{};
|
||||||
|
|
||||||
const ids = try wayland.registerGlobals(gpa, &id_pool, socket, &.{
|
const ids = try wayland.registerGlobals(gpa, &id_pool, conn.socket, &.{
|
||||||
wayland.core.Shm,
|
wayland.core.Shm,
|
||||||
wayland.core.Compositor,
|
wayland.core.Compositor,
|
||||||
wayland.xdg.WmBase,
|
wayland.xdg.WmBase,
|
||||||
|
@ -23,139 +23,101 @@ pub fn main() !void {
|
||||||
wayland.zxdg.DecorationManagerV1,
|
wayland.zxdg.DecorationManagerV1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const DISPLAY_ID = 1;
|
||||||
const shm_id = ids[0] orelse return error.NeccessaryWaylandExtensionMissing;
|
const shm_id = ids[0] orelse return error.NeccessaryWaylandExtensionMissing;
|
||||||
const compositor_id = ids[1] orelse return error.NeccessaryWaylandExtensionMissing;
|
const compositor_id = ids[1] orelse return error.NeccessaryWaylandExtensionMissing;
|
||||||
const xdg_wm_base_id = ids[2] orelse return error.NeccessaryWaylandExtensionMissing;
|
const xdg_wm_base_id = ids[2] orelse return error.NeccessaryWaylandExtensionMissing;
|
||||||
const wl_seat_id = ids[3] orelse return error.NeccessaryWaylandExtensionMissing;
|
const wl_seat_id = ids[3] orelse return error.NeccessaryWaylandExtensionMissing;
|
||||||
|
|
||||||
const surface_id = id_pool.create();
|
const surface_id = id_pool.create();
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Compositor.Request,
|
wayland.core.Compositor.Request,
|
||||||
&buffer,
|
|
||||||
compositor_id,
|
compositor_id,
|
||||||
.{ .create_surface = .{
|
.{ .create_surface = .{
|
||||||
.new_id = surface_id,
|
.new_id = surface_id,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
const xdg_surface_id = id_pool.create();
|
const xdg_surface_id = id_pool.create();
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.xdg.WmBase.Request,
|
wayland.xdg.WmBase.Request,
|
||||||
&buffer,
|
|
||||||
xdg_wm_base_id,
|
xdg_wm_base_id,
|
||||||
.{ .get_xdg_surface = .{
|
.{ .get_xdg_surface = .{
|
||||||
.id = xdg_surface_id,
|
.id = xdg_surface_id,
|
||||||
.surface = surface_id,
|
.surface = surface_id,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
const xdg_toplevel_id = id_pool.create();
|
const xdg_toplevel_id = id_pool.create();
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.xdg.Surface.Request,
|
wayland.xdg.Surface.Request,
|
||||||
&buffer,
|
|
||||||
xdg_surface_id,
|
xdg_surface_id,
|
||||||
.{ .get_toplevel = .{
|
.{ .get_toplevel = .{
|
||||||
.id = xdg_toplevel_id,
|
.id = xdg_toplevel_id,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
var zxdg_toplevel_decoration_id_opt: ?u32 = null;
|
var zxdg_toplevel_decoration_id_opt: ?u32 = null;
|
||||||
if (ids[4]) |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();
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.zxdg.DecorationManagerV1.Request,
|
wayland.zxdg.DecorationManagerV1.Request,
|
||||||
&buffer,
|
|
||||||
zxdg_decoration_manager_id,
|
zxdg_decoration_manager_id,
|
||||||
.{ .get_toplevel_decoration = .{
|
.{ .get_toplevel_decoration = .{
|
||||||
.new_id = zxdg_toplevel_decoration_id_opt.?,
|
.new_id = zxdg_toplevel_decoration_id_opt.?,
|
||||||
.toplevel = xdg_toplevel_id,
|
.toplevel = xdg_toplevel_id,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Surface.Request,
|
wayland.core.Surface.Request,
|
||||||
&buffer,
|
|
||||||
surface_id,
|
surface_id,
|
||||||
wayland.core.Surface.Request.commit,
|
wayland.core.Surface.Request.commit,
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
const registry_done_id = id_pool.create();
|
const registry_done_id = id_pool.create();
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [5]u32 = undefined;
|
wayland.core.Display.Request,
|
||||||
const message = try wayland.serialize(wayland.core.Display.Request, &buffer, 1, .{ .sync = .{ .callback = registry_done_id } });
|
DISPLAY_ID,
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
.{ .sync = .{ .callback = registry_done_id } },
|
||||||
}
|
);
|
||||||
|
|
||||||
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;
|
||||||
while (!done or !surface_configured) {
|
while (!done or !surface_configured) {
|
||||||
var header: wayland.Header = undefined;
|
const header, const body = try conn.recv();
|
||||||
const header_bytes_read = try socket.readAll(std.mem.asBytes(&header));
|
|
||||||
if (header_bytes_read < @sizeOf(wayland.Header)) {
|
|
||||||
return error.SocketClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 == xdg_surface_id) {
|
if (header.object_id == xdg_surface_id) {
|
||||||
const event = try wayland.deserialize(wayland.xdg.Surface.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.xdg.Surface.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.configure => |conf| {
|
.configure => |conf| {
|
||||||
var buffer: [10]u32 = undefined;
|
try conn.send(
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.xdg.Surface.Request,
|
wayland.xdg.Surface.Request,
|
||||||
&buffer,
|
|
||||||
xdg_surface_id,
|
xdg_surface_id,
|
||||||
.{ .ack_configure = .{
|
.{ .ack_configure = .{
|
||||||
.serial = conf.serial,
|
.serial = conf.serial,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
surface_configured = true;
|
surface_configured = true;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else if (zxdg_toplevel_decoration_id_opt != null and header.object_id == zxdg_toplevel_decoration_id_opt.?) {
|
} else if (zxdg_toplevel_decoration_id_opt != null and header.object_id == zxdg_toplevel_decoration_id_opt.?) {
|
||||||
const event = try wayland.deserialize(wayland.zxdg.ToplevelDecorationV1.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.zxdg.ToplevelDecorationV1.Event, header, body);
|
||||||
std.debug.print("<- zxdg_toplevel_decoration@{}\n", .{event});
|
std.debug.print("<- zxdg_toplevel_decoration@{}\n", .{event});
|
||||||
} else if (header.object_id == xdg_toplevel_id) {
|
} else if (header.object_id == xdg_toplevel_id) {
|
||||||
const event = try wayland.deserialize(wayland.xdg.Toplevel.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.xdg.Toplevel.Event, header, body);
|
||||||
std.debug.print("<- {}\n", .{event});
|
std.debug.print("<- {}\n", .{event});
|
||||||
} else if (header.object_id == registry_done_id) {
|
} else if (header.object_id == registry_done_id) {
|
||||||
done = true;
|
done = true;
|
||||||
} else if (header.object_id == shm_id) {
|
} else if (header.object_id == shm_id) {
|
||||||
const event = try wayland.deserialize(wayland.core.Shm.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.core.Shm.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.format => |format| std.debug.print("<- format {} {}\n", .{ format.format, std.zig.fmtEscapes(std.mem.asBytes(&format.format)) }),
|
.format => |format| std.debug.print("<- format {} {}\n", .{ format.format, std.zig.fmtEscapes(std.mem.asBytes(&format.format)) }),
|
||||||
}
|
}
|
||||||
} else if (header.object_id == wl_seat_id) {
|
} else if (header.object_id == wl_seat_id) {
|
||||||
const event = try wayland.deserialize(wayland.core.Seat.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.core.Seat.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.capabilities => |capabilities| {
|
.capabilities => |capabilities| {
|
||||||
const cap: wayland.core.Seat.Capability = @bitCast(capabilities.capability);
|
const cap: wayland.core.Seat.Capability = @bitCast(capabilities.capability);
|
||||||
|
@ -167,7 +129,7 @@ pub fn main() !void {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else if (header.object_id == 1) {
|
} else if (header.object_id == 1) {
|
||||||
const event = try wayland.deserialize(wayland.core.Display.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.core.Display.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.@"error" => |err| std.debug.print("<- error({}): {} {s}\n", .{ err.object_id, err.code, err.message }),
|
.@"error" => |err| std.debug.print("<- error({}): {} {s}\n", .{ err.object_id, err.code, err.message }),
|
||||||
.delete_id => |id| {
|
.delete_id => |id| {
|
||||||
|
@ -176,7 +138,7 @@ pub fn main() !void {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std.debug.print("{} {x} \"{}\"\n", .{ header.object_id, header.size_and_opcode.opcode, std.zig.fmtEscapes(std.mem.sliceAsBytes(message_buffer.items)) });
|
std.debug.print("{} {x} \"{}\"\n", .{ header.object_id, header.size_and_opcode.opcode, std.zig.fmtEscapes(std.mem.sliceAsBytes(body)) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,32 +146,26 @@ pub fn main() !void {
|
||||||
var wl_keyboard_id_opt: ?u32 = null;
|
var wl_keyboard_id_opt: ?u32 = null;
|
||||||
if (seat_capabilties) |caps| {
|
if (seat_capabilties) |caps| {
|
||||||
if (caps.pointer) {
|
if (caps.pointer) {
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
wl_pointer_id_opt = id_pool.create();
|
wl_pointer_id_opt = id_pool.create();
|
||||||
std.debug.print("wl pointer id: {}\n", .{wl_pointer_id_opt.?});
|
std.debug.print("wl pointer id: {}\n", .{wl_pointer_id_opt.?});
|
||||||
const message = try wayland.serialize(
|
try conn.send(
|
||||||
wayland.core.Seat.Request,
|
wayland.core.Seat.Request,
|
||||||
&buffer,
|
|
||||||
wl_seat_id,
|
wl_seat_id,
|
||||||
.{ .get_pointer = .{
|
.{ .get_pointer = .{
|
||||||
.new_id = wl_pointer_id_opt.?,
|
.new_id = wl_pointer_id_opt.?,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
}
|
||||||
if (caps.keyboard) {
|
if (caps.keyboard) {
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
wl_keyboard_id_opt = id_pool.create();
|
wl_keyboard_id_opt = id_pool.create();
|
||||||
std.debug.print("wl keyboard id: {}\n", .{wl_keyboard_id_opt.?});
|
std.debug.print("wl keyboard id: {}\n", .{wl_keyboard_id_opt.?});
|
||||||
const message = try wayland.serialize(
|
try conn.send(
|
||||||
wayland.core.Seat.Request,
|
wayland.core.Seat.Request,
|
||||||
&buffer,
|
|
||||||
wl_seat_id,
|
wl_seat_id,
|
||||||
.{ .get_keyboard = .{
|
.{ .get_keyboard = .{
|
||||||
.new_id = wl_keyboard_id_opt.?,
|
.new_id = wl_keyboard_id_opt.?,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const wl_pointer_id = wl_pointer_id_opt orelse return error.MissingPointer;
|
const wl_pointer_id = wl_pointer_id_opt orelse return error.MissingPointer;
|
||||||
|
@ -274,16 +230,12 @@ pub fn main() !void {
|
||||||
.controllen = @sizeOf(cmsg(std.os.fd_t)),
|
.controllen = @sizeOf(cmsg(std.os.fd_t)),
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
};
|
};
|
||||||
_ = try std.os.sendmsg(socket.handle, &socket_message, 0);
|
_ = try std.os.sendmsg(conn.socket.handle, &socket_message, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const wl_buffer_id = id_pool.create();
|
const wl_buffer_id = id_pool.create();
|
||||||
{
|
try conn.send(
|
||||||
std.debug.print("buffer id: {}\n", .{wl_buffer_id});
|
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.ShmPool.Request,
|
wayland.core.ShmPool.Request,
|
||||||
&buffer,
|
|
||||||
wl_shm_pool_id,
|
wl_shm_pool_id,
|
||||||
.{ .create_buffer = .{
|
.{ .create_buffer = .{
|
||||||
.new_id = wl_buffer_id,
|
.new_id = wl_buffer_id,
|
||||||
|
@ -294,14 +246,9 @@ pub fn main() !void {
|
||||||
.format = .argb8888,
|
.format = .argb8888,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Surface.Request,
|
wayland.core.Surface.Request,
|
||||||
&buffer,
|
|
||||||
surface_id,
|
surface_id,
|
||||||
.{ .attach = .{
|
.{ .attach = .{
|
||||||
.buffer = wl_buffer_id,
|
.buffer = wl_buffer_id,
|
||||||
|
@ -309,14 +256,9 @@ pub fn main() !void {
|
||||||
.y = 0,
|
.y = 0,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Surface.Request,
|
wayland.core.Surface.Request,
|
||||||
&buffer,
|
|
||||||
surface_id,
|
surface_id,
|
||||||
.{ .damage = .{
|
.{ .damage = .{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
|
@ -325,60 +267,39 @@ pub fn main() !void {
|
||||||
.height = std.math.maxInt(i32),
|
.height = std.math.maxInt(i32),
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
try conn.send(
|
||||||
var buffer: [10]u32 = undefined;
|
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.core.Surface.Request,
|
wayland.core.Surface.Request,
|
||||||
&buffer,
|
|
||||||
surface_id,
|
surface_id,
|
||||||
wayland.core.Surface.Request.commit,
|
wayland.core.Surface.Request.commit,
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
var running = true;
|
var running = true;
|
||||||
while (running) {
|
while (running) {
|
||||||
var header: wayland.Header = undefined;
|
const header, const body = try conn.recv();
|
||||||
const header_bytes_read = try socket.readAll(std.mem.asBytes(&header));
|
|
||||||
if (header_bytes_read < @sizeOf(wayland.Header)) {
|
|
||||||
return error.SocketClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 == xdg_surface_id) {
|
if (header.object_id == xdg_surface_id) {
|
||||||
const event = try wayland.deserialize(wayland.xdg.Surface.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.xdg.Surface.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.configure => |conf| {
|
.configure => |conf| {
|
||||||
var buffer: [10]u32 = undefined;
|
try conn.send(
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.xdg.Surface.Request,
|
wayland.xdg.Surface.Request,
|
||||||
&buffer,
|
|
||||||
xdg_surface_id,
|
xdg_surface_id,
|
||||||
.{ .ack_configure = .{
|
.{ .ack_configure = .{
|
||||||
.serial = conf.serial,
|
.serial = conf.serial,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
|
|
||||||
// commit the configuration
|
// commit the configuration
|
||||||
var buffer2: [10]u32 = undefined;
|
try conn.send(
|
||||||
const message2 = try wayland.serialize(
|
|
||||||
wayland.core.Surface.Request,
|
wayland.core.Surface.Request,
|
||||||
&buffer2,
|
|
||||||
surface_id,
|
surface_id,
|
||||||
wayland.core.Surface.Request.commit,
|
wayland.core.Surface.Request.commit,
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message2));
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else if (header.object_id == xdg_toplevel_id) {
|
} else if (header.object_id == xdg_toplevel_id) {
|
||||||
const event = try wayland.deserialize(wayland.xdg.Toplevel.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.xdg.Toplevel.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.configure => |conf| {
|
.configure => |conf| {
|
||||||
std.debug.print("<- xdg_toplevel@{} configure <{}, {}> {any}\n", .{ header.object_id, conf.width, conf.height, conf.states });
|
std.debug.print("<- xdg_toplevel@{} configure <{}, {}> {any}\n", .{ header.object_id, conf.width, conf.height, conf.states });
|
||||||
|
@ -387,29 +308,26 @@ pub fn main() !void {
|
||||||
else => |tag| std.debug.print("<- xdg_toplevel@{} {s} {}\n", .{ header.object_id, @tagName(tag), event }),
|
else => |tag| std.debug.print("<- xdg_toplevel@{} {s} {}\n", .{ header.object_id, @tagName(tag), event }),
|
||||||
}
|
}
|
||||||
} else if (header.object_id == wl_buffer_id) {
|
} else if (header.object_id == wl_buffer_id) {
|
||||||
const event = try wayland.deserialize(wayland.core.Buffer.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.core.Buffer.Event, header, body);
|
||||||
std.debug.print("<- wl_buffer@{} {}\n", .{ header.object_id, event });
|
std.debug.print("<- wl_buffer@{} {}\n", .{ header.object_id, event });
|
||||||
} else if (header.object_id == xdg_wm_base_id) {
|
} else if (header.object_id == xdg_wm_base_id) {
|
||||||
const event = try wayland.deserialize(wayland.xdg.WmBase.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.xdg.WmBase.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.ping => |ping| {
|
.ping => |ping| {
|
||||||
var buffer: [10]u32 = undefined;
|
try conn.send(
|
||||||
const message = try wayland.serialize(
|
|
||||||
wayland.xdg.WmBase.Request,
|
wayland.xdg.WmBase.Request,
|
||||||
&buffer,
|
|
||||||
xdg_wm_base_id,
|
xdg_wm_base_id,
|
||||||
.{ .pong = .{
|
.{ .pong = .{
|
||||||
.serial = ping.serial,
|
.serial = ping.serial,
|
||||||
} },
|
} },
|
||||||
);
|
);
|
||||||
try socket.writeAll(std.mem.sliceAsBytes(message));
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else if (header.object_id == wl_pointer_id) {
|
} else if (header.object_id == wl_pointer_id) {
|
||||||
const event = try wayland.deserialize(wayland.core.Pointer.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.core.Pointer.Event, header, body);
|
||||||
std.debug.print("<- wl_pointer@{}\n", .{event});
|
std.debug.print("<- wl_pointer@{}\n", .{event});
|
||||||
} else if (header.object_id == wl_keyboard_id) {
|
} else if (header.object_id == wl_keyboard_id) {
|
||||||
const event = try wayland.deserialize(wayland.core.Keyboard.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.core.Keyboard.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
// .keymap => |keymap| {},
|
// .keymap => |keymap| {},
|
||||||
else => {
|
else => {
|
||||||
|
@ -417,13 +335,13 @@ pub fn main() !void {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else if (header.object_id == 1) {
|
} else if (header.object_id == 1) {
|
||||||
const event = try wayland.deserialize(wayland.core.Display.Event, header, message_buffer.items);
|
const event = try wayland.deserialize(wayland.core.Display.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.@"error" => |err| std.debug.print("<- error({}): {} {s}\n", .{ err.object_id, err.code, err.message }),
|
.@"error" => |err| std.debug.print("<- error({}): {} {s}\n", .{ err.object_id, err.code, err.message }),
|
||||||
.delete_id => |id| id_pool.destroy(id.id),
|
.delete_id => |id| id_pool.destroy(id.id),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std.debug.print("{} {x} \"{}\"\n", .{ header.object_id, header.size_and_opcode.opcode, std.zig.fmtEscapes(std.mem.sliceAsBytes(message_buffer.items)) });
|
std.debug.print("{} {x} \"{}\"\n", .{ header.object_id, header.size_and_opcode.opcode, std.zig.fmtEscapes(std.mem.sliceAsBytes(body)) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
71
src/main.zig
71
src/main.zig
|
@ -353,8 +353,6 @@ pub fn registerGlobals(alloc: std.mem.Allocator, id_pool: *IdPool, socket: std.n
|
||||||
const Pair = struct { []const u8, Item };
|
const Pair = struct { []const u8, Item };
|
||||||
comptime var kvs_list: []const Pair = &[_]Pair{};
|
comptime var kvs_list: []const Pair = &[_]Pair{};
|
||||||
inline for (T, 0..) |t, i| {
|
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 } }};
|
kvs_list = kvs_list ++ &[_]Pair{.{ t.INTERFACE, .{ .version = t.VERSION, .index = i } }};
|
||||||
}
|
}
|
||||||
const map = std.ComptimeStringMap(Item, kvs_list);
|
const map = std.ComptimeStringMap(Item, kvs_list);
|
||||||
|
@ -407,9 +405,76 @@ pub fn registerGlobals(alloc: std.mem.Allocator, id_pool: *IdPool, socket: std.n
|
||||||
} else if (header.object_id == registry_done_id) {
|
} else if (header.object_id == registry_done_id) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
std.log.info("{} {x} \"{}\"", .{ header.object_id, header.size_and_opcode.opcode, std.zig.fmtEscapes(std.mem.sliceAsBytes(message_buffer.items)) });
|
std.log.info("{} {x} \"{}\"", .{
|
||||||
|
header.object_id,
|
||||||
|
header.size_and_opcode.opcode,
|
||||||
|
std.zig.fmtEscapes(std.mem.sliceAsBytes(message_buffer.items)),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const Conn = struct {
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
send_buffer: []u32,
|
||||||
|
recv_buffer: []u32,
|
||||||
|
socket: std.net.Stream,
|
||||||
|
|
||||||
|
pub fn init(alloc: std.mem.Allocator, display_path: []const u8) !Conn {
|
||||||
|
const send_buffer = try alloc.alloc(u32, 16);
|
||||||
|
const recv_buffer = try alloc.alloc(u32, 16);
|
||||||
|
return .{
|
||||||
|
.allocator = alloc,
|
||||||
|
.send_buffer = send_buffer,
|
||||||
|
.recv_buffer = recv_buffer,
|
||||||
|
.socket = try std.net.connectUnixSocket(display_path),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(conn: *Conn) void {
|
||||||
|
conn.allocator.free(conn.send_buffer);
|
||||||
|
conn.allocator.free(conn.recv_buffer);
|
||||||
|
conn.socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send(conn: *Conn, comptime Signature: type, id: u32, message: Signature) !void {
|
||||||
|
const msg = while (true) {
|
||||||
|
const msg = serialize(
|
||||||
|
Signature,
|
||||||
|
conn.send_buffer,
|
||||||
|
id,
|
||||||
|
message,
|
||||||
|
) catch |e| switch (e) {
|
||||||
|
error.OutOfMemory => {
|
||||||
|
conn.send_buffer = try conn.allocator.realloc(conn.send_buffer, conn.send_buffer.len * 2);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
break msg;
|
||||||
|
};
|
||||||
|
try conn.socket.writeAll(std.mem.sliceAsBytes(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Message = struct { Header, []const u32 };
|
||||||
|
pub fn recv(conn: *Conn) !Message {
|
||||||
|
var header: Header = undefined;
|
||||||
|
const header_bytes_read = try conn.socket.readAll(std.mem.asBytes(&header));
|
||||||
|
if (header_bytes_read < @sizeOf(Header)) {
|
||||||
|
return error.SocketClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const msg_size = (header.size_and_opcode.size - @sizeOf(Header)) / @sizeOf(u32);
|
||||||
|
if (msg_size > conn.recv_buffer.len) {
|
||||||
|
var new_size = conn.recv_buffer.len * 2;
|
||||||
|
while (new_size < msg_size) new_size *= 2;
|
||||||
|
conn.recv_buffer = try conn.allocator.realloc(conn.recv_buffer, new_size);
|
||||||
|
}
|
||||||
|
const bytes_read = try conn.socket.readAll(std.mem.sliceAsBytes(conn.recv_buffer[0..msg_size]));
|
||||||
|
const message = conn.recv_buffer[0 .. bytes_read / @sizeOf(u32)];
|
||||||
|
|
||||||
|
return .{ header, message };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue