They should use gpa.destroy() instead of foo.destroy() because (most) of them have fields that may not be initialized by the first error, so the foo.destroy() could crash.
74 lines
2.2 KiB
Zig
74 lines
2.2 KiB
Zig
// SPDX-FileCopyrightText: 2026 Ben Buhse <me@benbuhse.email>
|
|
//
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
const InputDevice = @This();
|
|
|
|
river_input_device_v1: *river.InputDeviceV1,
|
|
|
|
/// The LibinputDevice that corresponds to this same InputDevice.
|
|
/// This comes later (and from a separate river protocol) and
|
|
/// not all InputDevices are necessarily LibinputDevices, too,
|
|
/// so it's optional.
|
|
libinput_device: ?*LibinputDevice = null,
|
|
|
|
type: ?Type = null,
|
|
name: ?[]const u8 = null,
|
|
|
|
link: wl.list.Link,
|
|
|
|
pub fn create(river_input_device_v1: *river.InputDeviceV1) !*InputDevice {
|
|
const input_device = try utils.gpa.create(InputDevice);
|
|
errdefer utils.gpa.destroy(input_device);
|
|
|
|
input_device.* = .{
|
|
.river_input_device_v1 = river_input_device_v1,
|
|
.link = undefined, // handled by the wl.List
|
|
};
|
|
|
|
input_device.river_input_device_v1.setListener(
|
|
*InputDevice,
|
|
riverInputDeviceV1Listener,
|
|
input_device,
|
|
);
|
|
|
|
return input_device;
|
|
}
|
|
|
|
pub fn destroy(input_device: *InputDevice) void {
|
|
if (input_device.libinput_device) |libinput_device| {
|
|
libinput_device.input_device = null;
|
|
}
|
|
if (input_device.name) |name| {
|
|
utils.gpa.free(name);
|
|
}
|
|
input_device.link.remove();
|
|
utils.gpa.destroy(input_device);
|
|
}
|
|
|
|
fn riverInputDeviceV1Listener(river_input_device_v1: *river.InputDeviceV1, event: river.InputDeviceV1.Event, input_device: *InputDevice) void {
|
|
assert(input_device.river_input_device_v1 == river_input_device_v1);
|
|
switch (event) {
|
|
.removed => {
|
|
river_input_device_v1.destroy();
|
|
input_device.destroy();
|
|
},
|
|
.type => |ev| input_device.type = ev.type,
|
|
.name => |ev| input_device.name = utils.gpa.dupe(u8, mem.span(ev.name)) catch @panic("Out of memory"),
|
|
}
|
|
}
|
|
|
|
const std = @import("std");
|
|
const assert = std.debug.assert;
|
|
const mem = std.mem;
|
|
|
|
const wayland = @import("wayland");
|
|
const wl = wayland.client.wl;
|
|
const river = wayland.client.river;
|
|
const Type = river.InputDeviceV1.Type;
|
|
|
|
const utils = @import("utils.zig");
|
|
const Context = @import("Context.zig");
|
|
const LibinputDevice = @import("LibinputDevice.zig");
|
|
|
|
const log = std.log.scoped(.InputDevice);
|