From 847051ebc31eebdfea5648aa24a932416548c290 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Mon, 15 Jan 2024 02:22:40 -0700 Subject: [PATCH] feat: add seat, wl_pointer, wl_keyboard --- examples/01_client_connect.zig | 104 +++++++++++++++++--- src/core.zig | 170 +++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+), 14 deletions(-) diff --git a/examples/01_client_connect.zig b/examples/01_client_connect.zig index 87fa780..92b8beb 100644 --- a/examples/01_client_connect.zig +++ b/examples/01_client_connect.zig @@ -36,6 +36,7 @@ pub fn main() !void { 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(); @@ -111,6 +112,20 @@ pub fn main() !void { } }, ); 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 => {}, @@ -125,6 +140,7 @@ pub fn main() !void { 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(); { @@ -206,6 +222,7 @@ pub fn main() !void { var done = false; var surface_configured = false; + var seat_capabilties: ?wayland.core.Seat.Capability = null; while (!done or !surface_configured) { var header: wayland.Header = undefined; const header_bytes_read = try socket.readAll(std.mem.asBytes(&header)); @@ -237,20 +254,6 @@ pub fn main() !void { } 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); std.debug.print("<- zxdg_toplevel_decoration@{}\n", .{event}); - // switch (event) { - // .configure => |_| { - // var buffer: [10]u32 = undefined; - // const message = try wayland.serialize( - // wayland.zxdg.ToplevelDecorationV1.Request, - // &buffer, - // zxdg_toplevel_decoration_id_opt.?, - // .{ .set_mode = .{ - // .mode = .server_side, - // } }, - // ); - // try socket.writeAll(std.mem.sliceAsBytes(message)); - // }, - // } } else if (header.object_id == xdg_toplevel_id) { const event = try wayland.deserialize(wayland.xdg.Toplevel.Event, header, message_buffer.items); std.debug.print("<- {}\n", .{event}); @@ -261,6 +264,33 @@ pub fn main() !void { switch (event) { .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) { + const event = try wayland.deserialize(wayland.core.Seat.Event, header, message_buffer.items); + switch (event) { + .capabilities => |capabilities| { + const cap: wayland.core.Seat.Capability = @bitCast(capabilities.capability); + std.debug.print("<- wl_seat.capabilties = {}\n", .{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| { + std.debug.print("<- wl_seat.name = {s}\n", .{name.name}); + }, + } } else if (header.object_id == 1) { const event = try wayland.deserialize(wayland.core.Display.Event, header, message_buffer.items); switch (event) { @@ -275,6 +305,41 @@ pub fn main() !void { } } + var wl_pointer_id_opt: ?u32 = null; + var wl_keyboard_id_opt: ?u32 = null; + if (seat_capabilties) |caps| { + if (caps.pointer) { + var buffer: [10]u32 = undefined; + wl_pointer_id_opt = id_pool.create(); + std.debug.print("wl pointer id: {}\n", .{wl_pointer_id_opt.?}); + const message = try wayland.serialize( + wayland.core.Seat.Request, + &buffer, + wl_seat_id, + .{ .get_pointer = .{ + .new_id = wl_pointer_id_opt.?, + } }, + ); + try socket.writeAll(std.mem.sliceAsBytes(message)); + } + if (caps.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)); + } + } + const wl_pointer_id = wl_pointer_id_opt orelse return error.MissingPointer; + const wl_keyboard_id = wl_keyboard_id_opt orelse return error.MissingKeyboard; + // allocate a shared memory file for display purposes const Pixel = [4]u8; const framebuffer_size = [2]usize{ 128, 128 }; @@ -465,6 +530,17 @@ pub fn main() !void { try socket.writeAll(std.mem.sliceAsBytes(message)); }, } + } else if (header.object_id == wl_pointer_id) { + const event = try wayland.deserialize(wayland.core.Pointer.Event, header, message_buffer.items); + std.debug.print("<- wl_pointer@{}\n", .{event}); + } else if (header.object_id == wl_keyboard_id) { + const event = try wayland.deserialize(wayland.core.Keyboard.Event, header, message_buffer.items); + switch (event) { + // .keymap => |keymap| {}, + else => { + std.debug.print("<- wl_keyboard@{}\n", .{event}); + }, + } } else if (header.object_id == 1) { const event = try wayland.deserialize(wayland.core.Display.Event, header, message_buffer.items); switch (event) { diff --git a/src/core.zig b/src/core.zig index 946bc32..9ad1a1e 100644 --- a/src/core.zig +++ b/src/core.zig @@ -170,3 +170,173 @@ pub const Buffer = struct { release: void, }; }; + +pub const Seat = struct { + pub const Request = union(enum) { + get_pointer: struct { + new_id: u32, + }, + get_keyboard: struct { + new_id: u32, + }, + get_touch: struct { + new_id: u32, + }, + release: void, + }; + + pub const Event = union(enum) { + capabilities: struct { + capability: u32, + }, + name: struct { + name: []const u8, + }, + }; + + pub const Capability = packed struct(u32) { + pointer: bool, + keyboard: bool, + touch: bool, + _unused: u29, + }; + + pub const Error = enum(u32) {}; +}; + +pub const Pointer = struct { + pub const Request = union(enum) { + set_cursor: struct { + serial: u32, + surface: u32, + hotspot_x: i32, + hotspot_y: i32, + }, + release: void, + }; + + pub const Event = union(enum) { + enter: struct { + serial: u32, + surface: u32, + surface_x: u32, + surface_y: u32, + }, + leave: struct { + serial: u32, + surface: u32, + }, + motion: struct { + time: u32, + surface_x: i32, //i24.8 + surface_y: i32, //i24.8 + }, + button: struct { + serial: u32, + time: u32, + button: u32, + state: ButtonState, + }, + axis: struct { + time: u32, + axis: Axis, + value: i32, //i24.8 + }, + frame: void, + axis_source: struct { + axis_source: u32, + }, + axis_stop: struct { + time: u32, + axis: Axis, + }, + axis_discrete: struct { + axis: Axis, + discrete: i32, + }, + axis_value120: struct { + axis: Axis, + value120: i32, + }, + axis_relative_direction: struct { + axis: Axis, + direction: AxisRelativeDirection, + }, + }; + + pub const Error = enum(u32) { + role, + }; + + pub const ButtonState = enum(u32) { + released, + pressed, + }; + + pub const Axis = enum(u32) { + vertical_scroll, + horizontal_scroll, + }; + + pub const AxisSource = enum(u32) { + wheel, + finger, + continuous, + wheel_tilt, + }; + + pub const AxisRelativeDirection = enum(u32) { + identical, + inverted, + }; +}; + +pub const Keyboard = struct { + pub const Request = union(enum) { + release: void, + }; + + pub const Event = union(enum) { + keymap: struct { + format: KeymapFormat, + // fd: u32, + size: u32, + }, + enter: struct { + serial: u32, + surface: u32, + keys: []const u32, + }, + leave: struct { + serial: u32, + surface: u32, + }, + key: struct { + serial: u32, + time: u32, + key: u32, + state: KeyState, + }, + modifiers: struct { + serial: u32, + mods_depressed: u32, + mods_latched: u32, + mods_locked: u32, + group: u32, + }, + repeat_info: struct { + rate: i32, + delay: i32, + }, + }; + + pub const KeymapFormat = enum(u32) { + no_keymap, + xkb_v1, + }; + + pub const KeyState = enum(u32) { + released, + pressed, + }; +};