diff options
| author | Isaac Freund <ifreund@ifreund.xyz> | 2020-03-22 22:42:55 +0100 |
|---|---|---|
| committer | Isaac Freund <ifreund@ifreund.xyz> | 2020-03-22 22:42:55 +0100 |
| commit | 0584fde12625832d16a600a0900641cbb9a8b1c8 (patch) | |
| tree | 593f1f8504214b4ab0b3aad65f5fec8958e04b4f /src/seat.zig | |
| parent | 76ed2a72a8b83333e39b0ce7a04e0a519e4378e6 (diff) | |
| download | river-0584fde12625832d16a600a0900641cbb9a8b1c8.tar.gz river-0584fde12625832d16a600a0900641cbb9a8b1c8.tar.xz | |
WIP massive refactor
Diffstat (limited to 'src/seat.zig')
| -rw-r--r-- | src/seat.zig | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/seat.zig b/src/seat.zig new file mode 100644 index 0000000..7ec9b07 --- /dev/null +++ b/src/seat.zig @@ -0,0 +1,71 @@ +const std = @import("std"); +const c = @import("c.zig").c; + +// TODO: InputManager and multi-seat support +pub const Seat = struct { + server: *Server, + + wlr_seat: *c.wlr_seat, + listen_new_input: c.wl_listener, + + // Multiple mice are handled by the same Cursor + cursor: Cursor, + // Mulitple keyboards are handled separately + keyboards: std.ArrayList(Keyboard), + + pub fn init(server: *Server, allocator: *std.mem.Allocator) @This() { + var seat = @This(){ + .server = server, + // This seems to be the default seat name used by compositors + .wlr_seat = c.wlr_seat_create(server.*.wl_display, "seat0"), + .cursor = undefined, + .keyboards = std.ArrayList(Keyboard).init(allocator), + + .listen_new_input = c.wl_listener{ + .link = undefined, + .notify = handle_new_input, + }, + }; + + seat.cursor = cursor.Cursor.init(server); + + // Set up handler for all new input devices made available. This + // includes keyboards, pointers, touch, etc. + c.wl_signal_add(&server.*.backend.*.events.new_input, &seat.new_input); + } + + fn add_keyboard(self: *@This(), device: *c.wlr_input_device) void { + self.keyboards.append(Keyboard.init(self, device)); + c.wlr_seat_set_keyboard(self, device); + } + + fn add_pointer(self: *@This(), device: *c.struct_wlr_input_device) void { + // We don't do anything special with pointers. All of our pointer handling + // is proxied through wlr_cursor. On another compositor, you might take this + // opportunity to do libinput configuration on the device to set + // acceleration, etc. + c.wlr_cursor_attach_input_device(self.cursor.wlr_cursor, device); + } + + fn handle_new_input(listener: [*c]c.wl_listener, data: ?*c_void) callconv(.C) void { + // This event is raised by the backend when a new input device becomes available. + var seat = @fieldParentPtr(Seat, "listen_new_input", listener); + var device = @ptrCast(*c.wlr_input_device, @alignCast(@alignOf(*c.wlr_input_device), data)); + + switch (device.*.type) { + .WLR_INPUT_DEVICE_KEYBOARD => seat.add_keyboard(device), + .WLR_INPUT_DEVICE_POINTER => seat.add_pointer(device), + else => {}, + } + + // We need to let the wlr_seat know what our capabilities are, which is + // communiciated to the client. In TinyWL we always have a cursor, even if + // there are no pointer devices, so we always include that capability. + var caps: u32 = @intCast(u32, c.WL_SEAT_CAPABILITY_POINTER); + // if list not empty + if (c.wl_list_empty(&server.*.keyboards) == 0) { + caps |= @intCast(u32, c.WL_SEAT_CAPABILITY_KEYBOARD); + } + c.wlr_seat_set_capabilities(server.*.seat, caps); + } +}; |
