// Generated by zig-wayland

const std = @import("std");
const assert = std.debug.assert;
const posix = std.posix;

pub const client = struct {
    pub const wl = struct {
        pub const Object = common.Object;
        pub const Message = common.Message;
        pub const Interface = common.Interface;
        pub const list = common.list;
        pub const Array = common.Array;
        pub const Fixed = common.Fixed;
        pub const Argument = common.Argument;

        pub const Proxy = opaque {
            extern fn wl_proxy_create(factory: *Proxy, interface: *const Interface) ?*Proxy;
            pub fn create(factory: *Proxy, interface: *const Interface) error{OutOfMemory}!*Proxy {
                return wl_proxy_create(factory, interface) orelse error.OutOfMemory;
            }

            extern fn wl_proxy_destroy(proxy: *Proxy) void;
            pub const destroy = wl_proxy_destroy;

            extern fn wl_proxy_marshal_array(proxy: *Proxy, opcode: u32, args: ?[*]Argument) void;
            pub const marshal = wl_proxy_marshal_array;

            extern fn wl_proxy_marshal_array_constructor(
                proxy: *Proxy,
                opcode: u32,
                args: [*]Argument,
                interface: *const Interface,
            ) ?*Proxy;
            pub fn marshalConstructor(
                proxy: *Proxy,
                opcode: u32,
                args: [*]Argument,
                interface: *const Interface,
            ) error{OutOfMemory}!*Proxy {
                return wl_proxy_marshal_array_constructor(proxy, opcode, args, interface) orelse
                    error.OutOfMemory;
            }

            extern fn wl_proxy_marshal_array_constructor_versioned(
                proxy: *Proxy,
                opcode: u32,
                args: [*]Argument,
                interface: *const Interface,
                version: u32,
            ) ?*Proxy;
            pub fn marshalConstructorVersioned(
                proxy: *Proxy,
                opcode: u32,
                args: [*]Argument,
                interface: *const Interface,
                version: u32,
            ) error{OutOfMemory}!*Proxy {
                return wl_proxy_marshal_array_constructor_versioned(proxy, opcode, args, interface, version) orelse
                    error.OutOfMemory;
            }

            const DispatcherFn = fn (
                implementation: ?*const anyopaque,
                proxy: *Proxy,
                opcode: u32,
                message: *const Message,
                args: [*]Argument,
            ) callconv(.c) c_int;
            extern fn wl_proxy_add_dispatcher(
                proxy: *Proxy,
                dispatcher: *const DispatcherFn,
                implementation: ?*const anyopaque,
                data: ?*anyopaque,
            ) c_int;
            pub fn addDispatcher(
                proxy: *Proxy,
                dispatcher: *const DispatcherFn,
                implementation: ?*const anyopaque,
                data: ?*anyopaque,
            ) void {
                const ret = wl_proxy_add_dispatcher(proxy, dispatcher, implementation, data);
                // Since there is no way to remove listeners, adding a listener to
                // the same proxy twice is always a bug, so assert instead of returning
                // an error.
                assert(ret != -1); // If this fails, a listener was already added
            }

            extern fn wl_proxy_get_user_data(proxy: *Proxy) ?*anyopaque;
            pub const getUserData = wl_proxy_get_user_data;

            extern fn wl_proxy_get_version(proxy: *Proxy) u32;
            pub const getVersion = wl_proxy_get_version;

            extern fn wl_proxy_get_id(proxy: *Proxy) u32;
            pub const getId = wl_proxy_get_id;

            extern fn wl_proxy_set_queue(proxy: *Proxy, queue: *EventQueue) void;
            pub const setQueue = wl_proxy_set_queue;
        };

        pub const EventQueue = opaque {
            extern fn wl_event_queue_destroy(queue: *EventQueue) void;
            pub const destroy = wl_event_queue_destroy;
        };

        pub const EglWindow = opaque {
            extern fn wl_egl_window_create(surface: *client.wl.Surface, width: c_int, height: c_int) ?*EglWindow;
            pub fn create(surface: *client.wl.Surface, width: c_int, height: c_int) !*EglWindow {
                // Why do people use int when they require a positive number?
                assert(width > 0 and height > 0);
                return wl_egl_window_create(surface, width, height) orelse error.OutOfMemory;
            }

            extern fn wl_egl_window_destroy(egl_window: *EglWindow) void;
            pub const destroy = wl_egl_window_destroy;

            extern fn wl_egl_window_resize(egl_window: *EglWindow, width: c_int, height: c_int, dx: c_int, dy: c_int) void;
            pub const resize = wl_egl_window_resize;

            extern fn wl_egl_window_get_attached_size(egl_window: *EglWindow, width: *c_int, height: *c_int) void;
            pub const getAttachedSize = wl_egl_window_get_attached_size;
        };

        pub const CursorTheme = opaque {
            extern fn wl_cursor_theme_load(name: ?[*:0]const u8, size: c_int, shm: *client.wl.Shm) ?*CursorTheme;
            pub fn load(name: ?[*:0]const u8, size: i32, shm: *client.wl.Shm) error{LoadThemeFailed}!*CursorTheme {
                return wl_cursor_theme_load(name, @intCast(size), shm) orelse error.LoadThemeFailed;
            }

            extern fn wl_cursor_theme_destroy(wl_cursor_theme: *CursorTheme) void;
            pub const destroy = wl_cursor_theme_destroy;

            extern fn wl_cursor_theme_get_cursor(theme: *CursorTheme, name: [*:0]const u8) ?*Cursor;
            pub const getCursor = wl_cursor_theme_get_cursor;
        };

        pub const Cursor = extern struct {
            image_count: c_uint,
            images: [*]*CursorImage,
            name: [*:0]u8,

            extern fn wl_cursor_frame(cursor: *Cursor, time: u32) c_int;
            pub const frame = wl_cursor_frame;

            extern fn wl_cursor_frame_and_duration(cursor: *Cursor, time: u32, duration: *u32) c_int;
            pub const frameAndDuration = wl_cursor_frame_and_duration;
        };

        pub const CursorImage = extern struct {
            width: u32,
            height: u32,
            hotspot_x: u32,
            hotspot_y: u32,
            delay: u32,

            extern fn wl_cursor_image_get_buffer(image: *CursorImage) ?*client.wl.Buffer;
            pub fn getBuffer(image: *CursorImage) error{OutOfMemory}!*client.wl.Buffer {
                return wl_cursor_image_get_buffer(image) orelse error.OutOfMemory;
            }
        };
        pub const Display = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.display.interface;
            pub const Error = common.wl.display.Error;
            pub fn getId(_display: *Display) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_display)).getId();
            }
            pub fn getVersion(_display: *Display) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_display)).getVersion();
            }
            pub fn getUserData(_display: *Display) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_display)).getUserData();
            }
            pub fn setQueue(_display: *Display, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_display);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                @"error": struct {
                    object_id: ?*common.Object,
                    code: u32,
                    message: [*:0]const u8,
                },
                delete_id: struct {
                    id: u32,
                },
            };
            pub inline fn setListener(
                _display: *Display,
                comptime T: type,
                _listener: *const fn (display: *Display, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_display);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Display, T).dispatcher, _listener, _mut_data);
            }
            pub fn sync(_display: *Display) !*client.wl.Callback {
                const _proxy: *client.wl.Proxy = @ptrCast(_display);
                var _args = [_]common.Argument{
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructor(0, &_args, client.wl.Callback.interface));
            }
            pub fn getRegistry(_display: *Display) !*client.wl.Registry {
                const _proxy: *client.wl.Proxy = @ptrCast(_display);
                var _args = [_]common.Argument{
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructor(1, &_args, client.wl.Registry.interface));
            }
            extern fn wl_display_connect(name: ?[*:0]const u8) ?*Display;
            pub inline fn connect(name: ?[*:0]const u8) error{ConnectFailed}!*Display {
                return wl_display_connect(name) orelse return error.ConnectFailed;
            }

            extern fn wl_display_connect_to_fd(fd: c_int) ?*Display;
            pub inline fn connectToFd(fd: c_int) error{ConnectFailed}!*Display {
                return wl_display_connect_to_fd(fd) orelse return error.ConnectFailed;
            }

            extern fn wl_display_disconnect(display: *Display) void;
            pub const disconnect = wl_display_disconnect;

            extern fn wl_display_get_fd(display: *Display) c_int;
            pub const getFd = wl_display_get_fd;

            extern fn wl_display_dispatch(display: *Display) c_int;
            pub inline fn dispatch(display: *Display) posix.E {
                return posix.errno(wl_display_dispatch(display));
            }

            extern fn wl_display_dispatch_queue(display: *Display, queue: *client.wl.EventQueue) c_int;
            pub inline fn dispatchQueue(display: *Display, queue: *client.wl.EventQueue) posix.E {
                return posix.errno(wl_display_dispatch_queue(display, queue));
            }

            extern fn wl_display_dispatch_pending(display: *Display) c_int;
            pub inline fn dispatchPending(display: *Display) posix.E {
                return posix.errno(wl_display_dispatch_pending(display));
            }

            extern fn wl_display_dispatch_queue_pending(display: *Display, queue: *client.wl.EventQueue) c_int;
            pub inline fn dispatchQueuePending(display: *Display, queue: *client.wl.EventQueue) posix.E {
                return posix.errno(wl_display_dispatch_queue_pending(display, queue));
            }

            extern fn wl_display_roundtrip(display: *Display) c_int;
            pub inline fn roundtrip(display: *Display) posix.E {
                return posix.errno(wl_display_roundtrip(display));
            }

            extern fn wl_display_roundtrip_queue(display: *Display, queue: *client.wl.EventQueue) c_int;
            pub inline fn roundtripQueue(display: *Display, queue: *client.wl.EventQueue) posix.E {
                return posix.errno(wl_display_roundtrip_queue(display, queue));
            }

            extern fn wl_display_flush(display: *Display) c_int;
            pub inline fn flush(display: *Display) posix.E {
                return posix.errno(wl_display_flush(display));
            }

            extern fn wl_display_create_queue(display: *Display) ?*client.wl.EventQueue;
            pub inline fn createQueue(display: *Display) error{OutOfMemory}!*client.wl.EventQueue {
                return wl_display_create_queue(display) orelse error.OutOfMemory;
            }

            extern fn wl_display_get_error(display: *Display) c_int;
            pub const getError = wl_display_get_error;

            extern fn wl_display_prepare_read_queue(display: *Display, queue: *client.wl.EventQueue) c_int;
            /// Succeeds if the queue is empty and returns true.
            /// Fails and returns false if the queue was not empty.
            pub inline fn prepareReadQueue(display: *Display, queue: *client.wl.EventQueue) bool {
                switch (wl_display_prepare_read_queue(display, queue)) {
                    0 => return true,
                    -1 => return false,
                    else => unreachable,
                }
            }

            extern fn wl_display_prepare_read(display: *Display) c_int;
            /// Succeeds if the queue is empty and returns true.
            /// Fails and returns false if the queue was not empty.
            pub inline fn prepareRead(display: *Display) bool {
                switch (wl_display_prepare_read(display)) {
                    0 => return true,
                    -1 => return false,
                    else => unreachable,
                }
            }

            extern fn wl_display_cancel_read(display: *Display) void;
            pub const cancelRead = wl_display_cancel_read;

            extern fn wl_display_read_events(display: *Display) c_int;
            pub inline fn readEvents(display: *Display) posix.E {
                return posix.errno(wl_display_read_events(display));
            }
        };
        pub const Registry = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.registry.interface;
            pub fn getId(_registry: *Registry) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_registry)).getId();
            }
            pub fn getVersion(_registry: *Registry) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_registry)).getVersion();
            }
            pub fn getUserData(_registry: *Registry) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_registry)).getUserData();
            }
            pub fn setQueue(_registry: *Registry, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_registry);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                global: struct {
                    name: u32,
                    interface: [*:0]const u8,
                    version: u32,
                },
                global_remove: struct {
                    name: u32,
                },
            };
            pub inline fn setListener(
                _registry: *Registry,
                comptime T: type,
                _listener: *const fn (registry: *Registry, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_registry);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Registry, T).dispatcher, _listener, _mut_data);
            }
            pub fn bind(_registry: *Registry, _name: u32, comptime T: type, _version: u32) !*T {
                const version_to_construct = @min(T.generated_version, _version);
                const _proxy: *client.wl.Proxy = @ptrCast(_registry);
                var _args = [_]common.Argument{
                    .{ .u = _name },
                    .{ .s = T.interface.name },
                    .{ .u = version_to_construct },
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructorVersioned(0, &_args, T.interface, version_to_construct));
            }
            pub fn destroy(_registry: *Registry) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_registry);
                _proxy.destroy();
            }
        };
        pub const Callback = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.callback.interface;
            pub fn getId(_callback: *Callback) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_callback)).getId();
            }
            pub fn getVersion(_callback: *Callback) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_callback)).getVersion();
            }
            pub fn getUserData(_callback: *Callback) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_callback)).getUserData();
            }
            pub fn setQueue(_callback: *Callback, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_callback);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                done: struct {
                    callback_data: u32,
                },
            };
            pub inline fn setListener(
                _callback: *Callback,
                comptime T: type,
                _listener: *const fn (callback: *Callback, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_callback);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Callback, T).dispatcher, _listener, _mut_data);
            }
            pub fn destroy(_callback: *Callback) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_callback);
                _proxy.destroy();
            }
        };
        pub const Buffer = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.buffer.interface;
            pub fn getId(_buffer: *Buffer) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_buffer)).getId();
            }
            pub fn getVersion(_buffer: *Buffer) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_buffer)).getVersion();
            }
            pub fn getUserData(_buffer: *Buffer) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_buffer)).getUserData();
            }
            pub fn setQueue(_buffer: *Buffer, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_buffer);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                release: void,
            };
            pub inline fn setListener(
                _buffer: *Buffer,
                comptime T: type,
                _listener: *const fn (buffer: *Buffer, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_buffer);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Buffer, T).dispatcher, _listener, _mut_data);
            }
            pub fn destroy(_buffer: *Buffer) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_buffer);
                _proxy.marshal(0, null);
                _proxy.destroy();
            }
        };
        pub const Compositor = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.compositor.interface;
            pub fn getId(_compositor: *Compositor) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_compositor)).getId();
            }
            pub fn getVersion(_compositor: *Compositor) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_compositor)).getVersion();
            }
            pub fn getUserData(_compositor: *Compositor) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_compositor)).getUserData();
            }
            pub fn setQueue(_compositor: *Compositor, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_compositor);
                _proxy.setQueue(_queue);
            }
            pub fn createSurface(_compositor: *Compositor) !*client.wl.Surface {
                const _proxy: *client.wl.Proxy = @ptrCast(_compositor);
                var _args = [_]common.Argument{
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructor(0, &_args, client.wl.Surface.interface));
            }
            pub fn createRegion(_compositor: *Compositor) !*client.wl.Region {
                const _proxy: *client.wl.Proxy = @ptrCast(_compositor);
                var _args = [_]common.Argument{
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructor(1, &_args, client.wl.Region.interface));
            }
            pub fn destroy(_compositor: *Compositor) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_compositor);
                _proxy.destroy();
            }
        };
        pub const Surface = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.surface.interface;
            pub const Error = common.wl.surface.Error;
            pub fn getId(_surface: *Surface) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_surface)).getId();
            }
            pub fn getVersion(_surface: *Surface) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_surface)).getVersion();
            }
            pub fn getUserData(_surface: *Surface) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_surface)).getUserData();
            }
            pub fn setQueue(_surface: *Surface, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                enter: struct {
                    output: ?*client.wl.Output,
                },
                leave: struct {
                    output: ?*client.wl.Output,
                },
            };
            pub inline fn setListener(
                _surface: *Surface,
                comptime T: type,
                _listener: *const fn (surface: *Surface, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Surface, T).dispatcher, _listener, _mut_data);
            }
            pub fn destroy(_surface: *Surface) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                _proxy.marshal(0, null);
                _proxy.destroy();
            }
            pub fn attach(_surface: *Surface, _buffer: ?*client.wl.Buffer, _x: i32, _y: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .o = @ptrCast(_buffer) },
                    .{ .i = _x },
                    .{ .i = _y },
                };
                _proxy.marshal(1, &_args);
            }
            pub fn damage(_surface: *Surface, _x: i32, _y: i32, _width: i32, _height: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .i = _x },
                    .{ .i = _y },
                    .{ .i = _width },
                    .{ .i = _height },
                };
                _proxy.marshal(2, &_args);
            }
            pub fn frame(_surface: *Surface) !*client.wl.Callback {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructor(3, &_args, client.wl.Callback.interface));
            }
            pub fn setOpaqueRegion(_surface: *Surface, _region: ?*client.wl.Region) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .o = @ptrCast(_region) },
                };
                _proxy.marshal(4, &_args);
            }
            pub fn setInputRegion(_surface: *Surface, _region: ?*client.wl.Region) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .o = @ptrCast(_region) },
                };
                _proxy.marshal(5, &_args);
            }
            pub fn commit(_surface: *Surface) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                _proxy.marshal(6, null);
            }
            pub fn setBufferTransform(_surface: *Surface, _transform: common.wl.output.Transform) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .i = switch (@typeInfo(common.wl.output.Transform)) {
                        .@"enum" => @as(i32, @intCast(@intFromEnum(_transform))),
                        .@"struct" => @bitCast(_transform),
                        else => unreachable,
                    } },
                };
                _proxy.marshal(7, &_args);
            }
            pub fn setBufferScale(_surface: *Surface, _scale: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .i = _scale },
                };
                _proxy.marshal(8, &_args);
            }
            pub fn damageBuffer(_surface: *Surface, _x: i32, _y: i32, _width: i32, _height: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .i = _x },
                    .{ .i = _y },
                    .{ .i = _width },
                    .{ .i = _height },
                };
                _proxy.marshal(9, &_args);
            }
            pub fn offset(_surface: *Surface, _x: i32, _y: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .i = _x },
                    .{ .i = _y },
                };
                _proxy.marshal(10, &_args);
            }
        };
        pub const Region = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.region.interface;
            pub fn getId(_region: *Region) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_region)).getId();
            }
            pub fn getVersion(_region: *Region) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_region)).getVersion();
            }
            pub fn getUserData(_region: *Region) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_region)).getUserData();
            }
            pub fn setQueue(_region: *Region, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_region);
                _proxy.setQueue(_queue);
            }
            pub fn destroy(_region: *Region) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_region);
                _proxy.marshal(0, null);
                _proxy.destroy();
            }
            pub fn add(_region: *Region, _x: i32, _y: i32, _width: i32, _height: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_region);
                var _args = [_]common.Argument{
                    .{ .i = _x },
                    .{ .i = _y },
                    .{ .i = _width },
                    .{ .i = _height },
                };
                _proxy.marshal(1, &_args);
            }
            pub fn subtract(_region: *Region, _x: i32, _y: i32, _width: i32, _height: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_region);
                var _args = [_]common.Argument{
                    .{ .i = _x },
                    .{ .i = _y },
                    .{ .i = _width },
                    .{ .i = _height },
                };
                _proxy.marshal(2, &_args);
            }
        };
        pub const Shm = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.shm.interface;
            pub const Error = common.wl.shm.Error;
            pub const Format = common.wl.shm.Format;
            pub fn getId(_shm: *Shm) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_shm)).getId();
            }
            pub fn getVersion(_shm: *Shm) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_shm)).getVersion();
            }
            pub fn getUserData(_shm: *Shm) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_shm)).getUserData();
            }
            pub fn setQueue(_shm: *Shm, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_shm);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                format: struct {
                    format: Format,
                },
            };
            pub inline fn setListener(
                _shm: *Shm,
                comptime T: type,
                _listener: *const fn (shm: *Shm, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_shm);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Shm, T).dispatcher, _listener, _mut_data);
            }
            pub fn createPool(_shm: *Shm, _fd: i32, _size: i32) !*client.wl.ShmPool {
                const _proxy: *client.wl.Proxy = @ptrCast(_shm);
                var _args = [_]common.Argument{
                    .{ .o = null },
                    .{ .h = _fd },
                    .{ .i = _size },
                };
                return @ptrCast(try _proxy.marshalConstructor(0, &_args, client.wl.ShmPool.interface));
            }
            pub fn destroy(_shm: *Shm) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_shm);
                _proxy.destroy();
            }
        };
        pub const ShmPool = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.shm_pool.interface;
            pub fn getId(_shm_pool: *ShmPool) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_shm_pool)).getId();
            }
            pub fn getVersion(_shm_pool: *ShmPool) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_shm_pool)).getVersion();
            }
            pub fn getUserData(_shm_pool: *ShmPool) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_shm_pool)).getUserData();
            }
            pub fn setQueue(_shm_pool: *ShmPool, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_shm_pool);
                _proxy.setQueue(_queue);
            }
            pub fn createBuffer(_shm_pool: *ShmPool, _offset: i32, _width: i32, _height: i32, _stride: i32, _format: common.wl.shm.Format) !*client.wl.Buffer {
                const _proxy: *client.wl.Proxy = @ptrCast(_shm_pool);
                var _args = [_]common.Argument{
                    .{ .o = null },
                    .{ .i = _offset },
                    .{ .i = _width },
                    .{ .i = _height },
                    .{ .i = _stride },
                    .{ .u = switch (@typeInfo(common.wl.shm.Format)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_format))),
                        .@"struct" => @bitCast(_format),
                        else => unreachable,
                    } },
                };
                return @ptrCast(try _proxy.marshalConstructor(0, &_args, client.wl.Buffer.interface));
            }
            pub fn destroy(_shm_pool: *ShmPool) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_shm_pool);
                _proxy.marshal(1, null);
                _proxy.destroy();
            }
            pub fn resize(_shm_pool: *ShmPool, _size: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_shm_pool);
                var _args = [_]common.Argument{
                    .{ .i = _size },
                };
                _proxy.marshal(2, &_args);
            }
        };
        pub const Seat = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.seat.interface;
            pub const Capability = common.wl.seat.Capability;
            pub const Error = common.wl.seat.Error;
            pub fn getId(_seat: *Seat) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_seat)).getId();
            }
            pub fn getVersion(_seat: *Seat) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_seat)).getVersion();
            }
            pub fn getUserData(_seat: *Seat) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_seat)).getUserData();
            }
            pub fn setQueue(_seat: *Seat, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_seat);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                capabilities: struct {
                    capabilities: Capability,
                },
                name: struct {
                    name: [*:0]const u8,
                },
            };
            pub inline fn setListener(
                _seat: *Seat,
                comptime T: type,
                _listener: *const fn (seat: *Seat, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_seat);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Seat, T).dispatcher, _listener, _mut_data);
            }
            pub fn getPointer(_seat: *Seat) !*client.wl.Pointer {
                const _proxy: *client.wl.Proxy = @ptrCast(_seat);
                var _args = [_]common.Argument{
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructor(0, &_args, client.wl.Pointer.interface));
            }
            pub fn getKeyboard(_seat: *Seat) !*client.wl.Keyboard {
                const _proxy: *client.wl.Proxy = @ptrCast(_seat);
                var _args = [_]common.Argument{
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructor(1, &_args, client.wl.Keyboard.interface));
            }
            pub fn getTouch(_seat: *Seat) !*client.wl.Touch {
                const _proxy: *client.wl.Proxy = @ptrCast(_seat);
                var _args = [_]common.Argument{
                    .{ .o = null },
                };
                return @ptrCast(try _proxy.marshalConstructor(2, &_args, client.wl.Touch.interface));
            }
            pub fn release(_seat: *Seat) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_seat);
                _proxy.marshal(3, null);
                _proxy.destroy();
            }
            pub fn destroy(_seat: *Seat) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_seat);
                _proxy.destroy();
            }
        };
        pub const Pointer = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.pointer.interface;
            pub const Error = common.wl.pointer.Error;
            pub const ButtonState = common.wl.pointer.ButtonState;
            pub const Axis = common.wl.pointer.Axis;
            pub const AxisSource = common.wl.pointer.AxisSource;
            pub const AxisRelativeDirection = common.wl.pointer.AxisRelativeDirection;
            pub fn getId(_pointer: *Pointer) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_pointer)).getId();
            }
            pub fn getVersion(_pointer: *Pointer) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_pointer)).getVersion();
            }
            pub fn getUserData(_pointer: *Pointer) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_pointer)).getUserData();
            }
            pub fn setQueue(_pointer: *Pointer, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_pointer);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                enter: struct {
                    serial: u32,
                    surface: ?*client.wl.Surface,
                    surface_x: common.Fixed,
                    surface_y: common.Fixed,
                },
                leave: struct {
                    serial: u32,
                    surface: ?*client.wl.Surface,
                },
                motion: struct {
                    time: u32,
                    surface_x: common.Fixed,
                    surface_y: common.Fixed,
                },
                button: struct {
                    serial: u32,
                    time: u32,
                    button: u32,
                    state: ButtonState,
                },
                axis: struct {
                    time: u32,
                    axis: Axis,
                    value: common.Fixed,
                },
                frame: void,
                axis_source: struct {
                    axis_source: AxisSource,
                },
                axis_stop: struct {
                    time: u32,
                    axis: Axis,
                },
                axis_discrete: struct {
                    axis: Axis,
                    discrete: i32,
                },
            };
            pub inline fn setListener(
                _pointer: *Pointer,
                comptime T: type,
                _listener: *const fn (pointer: *Pointer, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_pointer);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Pointer, T).dispatcher, _listener, _mut_data);
            }
            pub fn setCursor(_pointer: *Pointer, _serial: u32, _surface: ?*client.wl.Surface, _hotspot_x: i32, _hotspot_y: i32) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .o = @ptrCast(_surface) },
                    .{ .i = _hotspot_x },
                    .{ .i = _hotspot_y },
                };
                _proxy.marshal(0, &_args);
            }
            pub fn release(_pointer: *Pointer) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_pointer);
                _proxy.marshal(1, null);
                _proxy.destroy();
            }
            pub fn destroy(_pointer: *Pointer) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_pointer);
                _proxy.destroy();
            }
        };
        pub const Keyboard = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.keyboard.interface;
            pub const KeymapFormat = common.wl.keyboard.KeymapFormat;
            pub const KeyState = common.wl.keyboard.KeyState;
            pub fn getId(_keyboard: *Keyboard) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_keyboard)).getId();
            }
            pub fn getVersion(_keyboard: *Keyboard) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_keyboard)).getVersion();
            }
            pub fn getUserData(_keyboard: *Keyboard) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_keyboard)).getUserData();
            }
            pub fn setQueue(_keyboard: *Keyboard, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_keyboard);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                keymap: struct {
                    format: KeymapFormat,
                    fd: i32,
                    size: u32,
                },
                enter: struct {
                    serial: u32,
                    surface: ?*client.wl.Surface,
                    keys: *common.Array,
                },
                leave: struct {
                    serial: u32,
                    surface: ?*client.wl.Surface,
                },
                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 inline fn setListener(
                _keyboard: *Keyboard,
                comptime T: type,
                _listener: *const fn (keyboard: *Keyboard, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_keyboard);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Keyboard, T).dispatcher, _listener, _mut_data);
            }
            pub fn release(_keyboard: *Keyboard) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_keyboard);
                _proxy.marshal(0, null);
                _proxy.destroy();
            }
            pub fn destroy(_keyboard: *Keyboard) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_keyboard);
                _proxy.destroy();
            }
        };
        pub const Touch = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.touch.interface;
            pub fn getId(_touch: *Touch) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_touch)).getId();
            }
            pub fn getVersion(_touch: *Touch) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_touch)).getVersion();
            }
            pub fn getUserData(_touch: *Touch) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_touch)).getUserData();
            }
            pub fn setQueue(_touch: *Touch, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_touch);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                down: struct {
                    serial: u32,
                    time: u32,
                    surface: ?*client.wl.Surface,
                    id: i32,
                    x: common.Fixed,
                    y: common.Fixed,
                },
                up: struct {
                    serial: u32,
                    time: u32,
                    id: i32,
                },
                motion: struct {
                    time: u32,
                    id: i32,
                    x: common.Fixed,
                    y: common.Fixed,
                },
                frame: void,
                cancel: void,
            };
            pub inline fn setListener(
                _touch: *Touch,
                comptime T: type,
                _listener: *const fn (touch: *Touch, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_touch);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Touch, T).dispatcher, _listener, _mut_data);
            }
            pub fn release(_touch: *Touch) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_touch);
                _proxy.marshal(0, null);
                _proxy.destroy();
            }
            pub fn destroy(_touch: *Touch) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_touch);
                _proxy.destroy();
            }
        };
        pub const Output = opaque {
            pub const generated_version = 4;
            pub const interface = &common.wl.output.interface;
            pub const Subpixel = common.wl.output.Subpixel;
            pub const Transform = common.wl.output.Transform;
            pub const Mode = common.wl.output.Mode;
            pub fn getId(_output: *Output) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_output)).getId();
            }
            pub fn getVersion(_output: *Output) u32 {
                return @as(*client.wl.Proxy, @ptrCast(_output)).getVersion();
            }
            pub fn getUserData(_output: *Output) ?*anyopaque {
                return @as(*client.wl.Proxy, @ptrCast(_output)).getUserData();
            }
            pub fn setQueue(_output: *Output, _queue: *client.wl.EventQueue) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_output);
                _proxy.setQueue(_queue);
            }
            pub const Event = union(enum) {
                geometry: struct {
                    x: i32,
                    y: i32,
                    physical_width: i32,
                    physical_height: i32,
                    subpixel: Subpixel,
                    make: [*:0]const u8,
                    model: [*:0]const u8,
                    transform: Transform,
                },
                mode: struct {
                    flags: Mode,
                    width: i32,
                    height: i32,
                    refresh: i32,
                },
                done: void,
                scale: struct {
                    factor: i32,
                },
                name: struct {
                    name: [*:0]const u8,
                },
                description: struct {
                    description: [*:0]const u8,
                },
            };
            pub inline fn setListener(
                _output: *Output,
                comptime T: type,
                _listener: *const fn (output: *Output, event: Event, data: T) void,
                _data: T,
            ) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_output);
                const _mut_data: ?*anyopaque = @ptrFromInt(@intFromPtr(_data));
                _proxy.addDispatcher(common.Dispatcher(Output, T).dispatcher, _listener, _mut_data);
            }
            pub fn release(_output: *Output) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_output);
                _proxy.marshal(0, null);
                _proxy.destroy();
            }
            pub fn destroy(_output: *Output) void {
                const _proxy: *client.wl.Proxy = @ptrCast(_output);
                _proxy.destroy();
            }
        };
    };
};

pub const server = struct {
    pub const wl = struct {
        pub const Object = common.Object;
        pub const Message = common.Message;
        pub const Interface = common.Interface;
        pub const list = common.list;
        pub const Array = common.Array;
        pub const Fixed = common.Fixed;
        pub const Argument = common.Argument;

        /// This is wayland-server's wl_display. It has been renamed as zig-wayland has
        /// decided to hide wl_resources with opaque pointers in the same way that
        /// wayland-client does with wl_proxys. This of course creates a name conflict.
        pub const Server = opaque {
            extern fn wl_display_create() ?*Server;
            pub fn create() !*Server {
                return wl_display_create() orelse error.ServerCreateFailed;
            }

            extern fn wl_display_destroy(server: *Server) void;
            pub const destroy = wl_display_destroy;

            extern fn wl_display_get_event_loop(server: *Server) *EventLoop;
            pub const getEventLoop = wl_display_get_event_loop;

            extern fn wl_display_add_socket(server: *Server, name: [*:0]const u8) c_int;
            pub fn addSocket(_server: *Server, name: [*:0]const u8) !void {
                if (wl_display_add_socket(_server, name) == -1)
                    return error.AddSocketFailed;
            }

            // wayland-client will connect to wayland-0 even if WAYLAND_DISPLAY is
            // unset due to an unfortunate piece of code that was not removed before
            // the library was stabilized. Because of this, it is a good idea to never
            // call the socket wayland-0. So, instead of binding to wayland-server's
            // wl_display_add_socket_auto we implement a version which skips wayland-0.
            pub fn addSocketAuto(_server: *Server, buf: *[11]u8) ![:0]const u8 {
                // Don't use wayland-0
                var i: u32 = 1;
                while (i <= 32) : (i += 1) {
                    const name = std.fmt.bufPrintZ(buf, "wayland-{}", .{i}) catch unreachable;
                    _server.addSocket(name.ptr) catch continue;
                    return name;
                }
                return error.AddSocketFailed;
            }

            extern fn wl_display_add_socket_fd(_server: *Server, sock_fd: c_int) c_int;
            pub fn addSocketFd(_server: *Server, sock_fd: c_int) !void {
                if (wl_display_add_socket_fd(_server, sock_fd) == -1)
                    return error.AddSocketFailed;
            }

            extern fn wl_display_terminate(_server: *Server) void;
            pub const terminate = wl_display_terminate;

            extern fn wl_display_run(_server: *Server) void;
            pub const run = wl_display_run;

            extern fn wl_display_flush_clients(_server: *Server) void;
            pub const flushClients = wl_display_flush_clients;

            extern fn wl_display_destroy_clients(_server: *Server) void;
            pub const destroyClients = wl_display_destroy_clients;

            extern fn wl_display_get_serial(_server: *Server) u32;
            pub const getSerial = wl_display_get_serial;

            extern fn wl_display_next_serial(_server: *Server) u32;
            pub const nextSerial = wl_display_next_serial;

            extern fn wl_display_add_destroy_listener(_server: *Server, listener: *Listener(*Server)) void;
            pub const addDestroyListener = wl_display_add_destroy_listener;

            extern fn wl_display_add_client_created_listener(_server: *Server, listener: *Listener(*Client)) void;
            pub const addClientCreatedListener = wl_display_add_client_created_listener;

            // Doesn't really make sense with our Listener API as we would need to
            // pass a pointer to the wrapper function
            //extern fn wl_display_get_destroy_listener(_server: *Server, notify: @TypeOf(Listener(*Server).notify)) ?*Listener(*Server);

            extern fn wl_display_set_global_filter(
                _server: *Server,
                filter: *const fn (_client: *const Client, global: *const Global, data: ?*anyopaque) callconv(.c) bool,
                data: ?*anyopaque,
            ) void;
            pub inline fn setGlobalFilter(
                _server: *Server,
                comptime T: type,
                comptime filter: fn (_client: *const Client, global: *const Global, data: T) bool,
                data: T,
            ) void {
                wl_display_set_global_filter(
                    _server,
                    struct {
                        fn _wrapper(_client: *const Client, _global: *const Global, _data: ?*anyopaque) callconv(.c) bool {
                            return filter(_client, _global, @ptrCast(@alignCast(_data)));
                        }
                    }._wrapper,
                    data,
                );
            }

            extern fn wl_display_get_client_list(_server: *Server) *list.Head(Client, null);
            pub const getClientList = wl_display_get_client_list;

            extern fn wl_display_init_shm(_server: *Server) c_int;
            pub fn initShm(_server: *Server) !void {
                if (wl_display_init_shm(_server) == -1) return error.OutOfMemory;
            }

            extern fn wl_display_add_shm_format(_server: *Server, format: u32) ?*u32;
            pub fn addShmFormat(_server: *Server, format: u32) !*u32 {
                return wl_display_add_shm_format(_server, format) orelse error.OutOfMemory;
            }

            extern fn wl_display_add_protocol_logger(
                _server: *Server,
                func: *const fn (data: ?*anyopaque, direction: ProtocolLogger.Type, message: *const ProtocolLogger.LogMessage) callconv(.c) void,
                data: ?*anyopaque,
            ) void;
            pub inline fn addProtocolLogger(
                _server: *Server,
                comptime T: type,
                comptime func: fn (data: T, direction: ProtocolLogger.Type, message: *const ProtocolLogger.LogMessage) void,
                data: T,
            ) void {
                wl_display_add_protocol_logger(
                    _server,
                    struct {
                        fn _wrapper(_data: ?*anyopaque, _direction: ProtocolLogger.Type, _message: *const ProtocolLogger.LogMessage) callconv(.c) void {
                            func(@ptrCast(@alignCast(_data)), _direction, _message);
                        }
                    }._wrapper,
                    data,
                );
            }
        };

        pub const Client = opaque {
            extern fn wl_client_create(_server: *Server, fd: c_int) ?*Client;
            pub const create = wl_client_create;

            extern fn wl_client_destroy(_client: *Client) void;
            pub const destroy = wl_client_destroy;

            extern fn wl_client_flush(_client: *Client) void;
            pub const flush = wl_client_flush;

            extern fn wl_client_get_link(_client: *Client) *list.Link;
            pub const getLink = wl_client_get_link;

            extern fn wl_client_from_link(link: *list.Link) *Client;
            pub const fromLink = wl_client_from_link;

            const Credentials = struct {
                pid: posix.pid_t,
                gid: posix.gid_t,
                uid: posix.uid_t,
            };
            extern fn wl_client_get_credentials(_client: *Client, pid: *posix.pid_t, uid: *posix.uid_t, gid: *posix.gid_t) void;
            pub fn getCredentials(_client: *Client) Credentials {
                var credentials: Credentials = undefined;
                wl_client_get_credentials(_client, &credentials.pid, &credentials.uid, &credentials.gid);
                return credentials;
            }

            extern fn wl_client_add_destroy_listener(_client: *Client, listener: *Listener(*Client)) void;
            pub const addDestroyListener = wl_client_add_destroy_listener;

            // Doesn't really make sense with our Listener API as we would need to
            // pass a pointer to the wrapper function
            //extern fn wl_client_get_destroy_listener(_client: *Client, notify: @TypeOf(Listener(*Client).notify)) ?*Listener(*Client);

            extern fn wl_client_get_object(_client: *Client, id: u32) ?*Resource;
            pub const getObject = wl_client_get_object;

            extern fn wl_client_post_no_memory(_client: *Client) void;
            pub const postNoMemory = wl_client_post_no_memory;

            extern fn wl_client_post_implementation_error(_client: *Client, msg: [*:0]const u8, ...) void;
            pub const postImplementationError = wl_client_post_implementation_error;

            extern fn wl_client_add_resource_created_listener(_client: *Client, listener: *Listener(*Resource)) void;
            pub const addResourceCreatedListener = wl_client_add_resource_created_listener;

            const IteratorResult = enum(c_int) { stop, cont };
            extern fn wl_client_for_each_resource(
                _client: *Client,
                iterator: *const fn (resource: *Resource, data: ?*anyopaque) callconv(.c) IteratorResult,
                data: ?*anyopaque,
            ) void;
            pub inline fn forEachResource(
                _client: *Client,
                comptime T: type,
                comptime iterator: fn (resource: *Resource, data: T) IteratorResult,
                data: T,
            ) void {
                wl_client_for_each_resource(
                    _client,
                    struct {
                        fn _wrapper(_resource: *Resource, _data: ?*anyopaque) callconv(.c) IteratorResult {
                            return iterator(_resource, @ptrCast(@alignCast(_data)));
                        }
                    }._wrapper,
                    data,
                );
            }

            extern fn wl_client_get_fd(_client: *Client) c_int;
            pub const getFd = wl_client_get_fd;

            extern fn wl_client_get_display(_client: *Client) *Server;
            pub const getDisplay = wl_client_get_display;
        };

        pub const Global = opaque {
            extern fn wl_global_create(
                _server: *Server,
                interface: *const Interface,
                version: c_int,
                data: ?*anyopaque,
                bind: *const fn (_client: *Client, data: ?*anyopaque, version: u32, id: u32) callconv(.c) void,
            ) ?*Global;
            pub inline fn create(
                _server: *Server,
                comptime T: type,
                version: u32,
                comptime DataT: type,
                data: DataT,
                comptime bind: fn (_client: *Client, data: DataT, version: u32, id: u32) void,
            ) error{GlobalCreateFailed}!*Global {
                return wl_global_create(
                    _server,
                    T.interface,
                    @as(c_int, @intCast(version)),
                    data,
                    struct {
                        fn _wrapper(_client: *Client, _data: ?*anyopaque, _version: u32, _id: u32) callconv(.c) void {
                            bind(_client, @ptrCast(@alignCast(_data)), _version, _id);
                        }
                    }._wrapper,
                ) orelse error.GlobalCreateFailed;
            }

            extern fn wl_global_remove(global: *Global) void;
            pub const remove = wl_global_remove;

            extern fn wl_global_destroy(global: *Global) void;
            pub const destroy = wl_global_destroy;

            extern fn wl_global_get_interface(global: *const Global) *const Interface;
            pub const getInterface = wl_global_get_interface;

            extern fn wl_global_get_name(global: *const Global, _client: *const Client) u32;
            pub const getName = wl_global_get_name;

            extern fn wl_global_get_user_data(global: *const Global) ?*anyopaque;
            pub const getUserData = wl_global_get_user_data;
        };

        pub const Resource = opaque {
            extern fn wl_resource_create(_client: *Client, interface: *const Interface, version: c_int, id: u32) ?*Resource;
            pub inline fn create(_client: *Client, comptime T: type, version: u32, id: u32) error{ResourceCreateFailed}!*Resource {
                // This is only a c_int because of legacy libwayland reasons. Negative versions are invalid.
                // Version is a u32 on the wire and for wl_global, wl_proxy, etc.
                return wl_resource_create(_client, T.interface, @as(c_int, @intCast(version)), id) orelse error.ResourceCreateFailed;
            }

            extern fn wl_resource_destroy(resource: *Resource) void;
            pub const destroy = wl_resource_destroy;

            extern fn wl_resource_post_event_array(resource: *Resource, opcode: u32, args: ?[*]Argument) void;
            pub const postEvent = wl_resource_post_event_array;

            extern fn wl_resource_queue_event_array(resource: *Resource, opcode: u32, args: ?[*]Argument) void;
            pub const queueEvent = wl_resource_queue_event_array;

            extern fn wl_resource_post_error(resource: *Resource, code: u32, message: [*:0]const u8, ...) void;
            pub const postError = wl_resource_post_error;

            extern fn wl_resource_post_no_memory(resource: *Resource) void;
            pub const postNoMemory = wl_resource_post_no_memory;

            const DispatcherFn = fn (
                implementation: ?*const anyopaque,
                resource: *Resource,
                opcode: u32,
                message: *const Message,
                args: [*]Argument,
            ) callconv(.c) c_int;
            pub const DestroyFn = fn (resource: *Resource) callconv(.c) void;
            extern fn wl_resource_set_dispatcher(
                resource: *Resource,
                dispatcher: ?*const DispatcherFn,
                implementation: ?*const anyopaque,
                data: ?*anyopaque,
                destroy_fn: ?*const DestroyFn,
            ) void;
            pub fn setDispatcher(
                resource: *Resource,
                dispatcher: ?*const DispatcherFn,
                implementation: ?*const anyopaque,
                data: ?*anyopaque,
                destroy_fn: ?*const DestroyFn,
            ) void {
                wl_resource_set_dispatcher(resource, dispatcher, implementation, data, destroy_fn);
            }

            extern fn wl_resource_get_user_data(resource: *Resource) ?*anyopaque;
            pub const getUserData = wl_resource_get_user_data;

            extern fn wl_resource_get_id(resource: *Resource) u32;
            pub const getId = wl_resource_get_id;

            extern fn wl_resource_get_link(resource: *Resource) *list.Link;
            pub const getLink = wl_resource_get_link;

            extern fn wl_resource_from_link(link: *list.Link) *Resource;
            pub const fromLink = wl_resource_from_link;

            extern fn wl_resource_find_for_client(list: *list.Head(Resource, null), _client: *Client) ?*Resource;
            pub const findForClient = wl_resource_find_for_client;

            extern fn wl_resource_get_client(resource: *Resource) *Client;
            pub const getClient = wl_resource_get_client;

            extern fn wl_resource_get_version(resource: *Resource) c_int;
            pub fn getVersion(resource: *Resource) u32 {
                // The fact that wl_resource.version is a int in libwayland is
                // a mistake. Negative versions are impossible and u32 is used
                // everywhere else in libwayland
                return @as(u32, @intCast(wl_resource_get_version(resource)));
            }

            // TOOD: unsure if this should be bound
            extern fn wl_resource_set_destructor(resource: *Resource, destroy: DestroyFn) void;

            extern fn wl_resource_get_class(resource: *Resource) [*:0]const u8;
            pub const getClass = wl_resource_get_class;

            extern fn wl_resource_add_destroy_listener(resource: *Resource, listener: *Listener(*Resource)) void;
            pub const addDestroyListener = wl_resource_add_destroy_listener;

            // Doesn't really make sense with our Listener API as we would need to
            // pass a pointer to the wrapper function
            //extern fn wl_resource_get_destroy_listener(resource: *Resource, notify: @TypeOf(Listener(*Resource).notify)) ?*Listener(*Resource);
        };

        pub const ProtocolLogger = opaque {
            pub const Type = enum(c_int) {
                request,
                event,
            };

            pub const LogMessage = extern struct {
                resource: *Resource,
                message_opcode: c_int,
                message: *Message,
                arguments_count: c_int,
                arguments: ?[*]Argument,
            };

            extern fn wl_protocol_logger_destroy(logger: *ProtocolLogger) void;
            pub const destroy = wl_protocol_logger_destroy;
        };

        pub fn Listener(comptime T: type) type {
            return extern struct {
                const Self = @This();

                pub const NotifyFn = if (T == void)
                    fn (listener: *Self) void
                else
                    fn (listener: *Self, data: T) void;

                link: list.Link,
                notify: *const fn (listener: *Self, data: ?*anyopaque) callconv(.c) void,

                pub fn init(comptime notify: NotifyFn) Self {
                    var self: Self = undefined;
                    self.setNotify(notify);
                    return self;
                }

                pub fn setNotify(self: *Self, comptime notify: NotifyFn) void {
                    self.notify = if (T == void)
                        struct {
                            fn wrapper(listener: *Self, _: ?*anyopaque) callconv(.c) void {
                                @call(.always_inline, notify, .{listener});
                            }
                        }.wrapper
                    else
                        struct {
                            fn wrapper(listener: *Self, data: ?*anyopaque) callconv(.c) void {
                                @call(.always_inline, notify, .{ listener, @as(T, @ptrFromInt(@intFromPtr(data))) });
                            }
                        }.wrapper;
                }
            };
        }

        pub fn Signal(comptime T: type) type {
            return extern struct {
                const Self = @This();

                listener_list: list.Head(Listener(T), .link),

                pub fn init(signal: *Self) void {
                    signal.listener_list.init();
                }

                pub fn add(signal: *Self, listener: *Listener(T)) void {
                    signal.listener_list.append(listener);
                }

                pub fn get(signal: *Self, notify: @TypeOf(Listener(T).notify)) ?*Listener(T) {
                    var it = signal.listener_list.iterator(.forward);
                    return while (it.next()) |listener| {
                        if (listener.notify == notify) break listener;
                    } else null;
                }

                pub const emit = if (T == void)
                    struct {
                        pub inline fn emit(signal: *Self) void {
                            emitInner(signal, null);
                        }
                    }.emit
                else
                    struct {
                        pub inline fn emit(signal: *Self, data: T) void {
                            emitInner(signal, data);
                        }
                    }.emit;

                /// This is similar to wlroots' wlr_signal_emit_safe. It handles
                /// removal of any element in the list during iteration and stops at
                /// whatever the last element was when iteration started.
                fn emitInner(signal: *Self, data: ?*anyopaque) void {
                    var cursor: Listener(T) = undefined;
                    signal.listener_list.prepend(&cursor);

                    var end: Listener(T) = undefined;
                    signal.listener_list.append(&end);

                    while (cursor.link.next != &end.link) {
                        const pos = cursor.link.next.?;
                        const listener: *Listener(T) = @fieldParentPtr("link", pos);

                        cursor.link.remove();
                        pos.insert(&cursor.link);

                        listener.notify(listener, data);
                    }

                    cursor.link.remove();
                    end.link.remove();
                }
            };
        }

        pub const EventMask = packed struct(u32) {
            readable: bool = false,
            writable: bool = false,
            hangup: bool = false,
            @"error": bool = false,

            _: u28 = 0,
        };

        pub const EventLoop = opaque {
            extern fn wl_event_loop_create() ?*EventLoop;
            pub fn create() !*EventLoop {
                return wl_event_loop_create() orelse error.EventLoopCreateFailed;
            }

            extern fn wl_event_loop_destroy(loop: *EventLoop) void;
            pub const destroy = wl_event_loop_destroy;

            extern fn wl_event_loop_add_fd(
                loop: *EventLoop,
                fd: c_int,
                mask: u32,
                func: *const fn (fd: c_int, mask: u32, data: ?*anyopaque) callconv(.c) c_int,
                data: ?*anyopaque,
            ) ?*EventSource;
            pub inline fn addFd(
                loop: *EventLoop,
                comptime T: type,
                fd: c_int,
                mask: EventMask,
                comptime func: fn (fd: c_int, mask: EventMask, data: T) c_int,
                data: T,
            ) error{AddFdFailed}!*EventSource {
                return wl_event_loop_add_fd(
                    loop,
                    fd,
                    mask,
                    struct {
                        fn _wrapper(_fd: c_int, _mask: u32, _data: ?*anyopaque) callconv(.c) c_int {
                            return func(_fd, @bitCast(_mask), @ptrCast(@alignCast(_data)));
                        }
                    }._wrapper,
                    data,
                ) orelse error.AddFdFailed;
            }

            extern fn wl_event_loop_add_timer(
                loop: *EventLoop,
                func: *const fn (data: ?*anyopaque) callconv(.c) c_int,
                data: ?*anyopaque,
            ) ?*EventSource;
            pub inline fn addTimer(
                loop: *EventLoop,
                comptime T: type,
                comptime func: fn (data: T) c_int,
                data: T,
            ) error{AddTimerFailed}!*EventSource {
                return wl_event_loop_add_timer(
                    loop,
                    struct {
                        fn _wrapper(_data: ?*anyopaque) callconv(.c) c_int {
                            return func(@ptrCast(@alignCast(_data)));
                        }
                    }._wrapper,
                    data,
                ) orelse error.AddTimerFailed;
            }

            extern fn wl_event_loop_add_signal(
                loop: *EventLoop,
                signal_number: c_int,
                func: *const fn (c_int, ?*anyopaque) callconv(.c) c_int,
                data: ?*anyopaque,
            ) ?*EventSource;
            pub inline fn addSignal(
                loop: *EventLoop,
                comptime T: type,
                signal_number: c_int,
                comptime func: fn (signal_number: c_int, data: T) c_int,
                data: T,
            ) error{AddSignalFailed}!*EventSource {
                return wl_event_loop_add_signal(
                    loop,
                    signal_number,
                    struct {
                        fn _wrapper(_signal_number: c_int, _data: ?*anyopaque) callconv(.c) c_int {
                            return func(_signal_number, @ptrCast(@alignCast(_data)));
                        }
                    }._wrapper,
                    data,
                ) orelse error.AddSignalFailed;
            }

            extern fn wl_event_loop_add_idle(
                loop: *EventLoop,
                func: *const fn (data: ?*anyopaque) callconv(.c) void,
                data: ?*anyopaque,
            ) ?*EventSource;
            pub inline fn addIdle(
                loop: *EventLoop,
                comptime T: type,
                comptime func: fn (data: T) void,
                data: T,
            ) error{OutOfMemory}!*EventSource {
                return wl_event_loop_add_idle(
                    loop,
                    struct {
                        fn _wrapper(_data: ?*anyopaque) callconv(.c) void {
                            return func(@ptrCast(@alignCast(_data)));
                        }
                    }._wrapper,
                    data,
                ) orelse error.OutOfMemory;
            }

            extern fn wl_event_loop_dispatch(loop: *EventLoop, timeout: c_int) c_int;
            pub fn dispatch(loop: *EventLoop, timeout: c_int) !void {
                const rc = wl_event_loop_dispatch(loop, timeout);
                switch (posix.errno(rc)) {
                    .SUCCESS => return,
                    // TODO
                    else => |err| return posix.unexpectedErrno(err),
                }
            }

            extern fn wl_event_loop_dispatch_idle(loop: *EventLoop) void;
            pub const dispatchIdle = wl_event_loop_dispatch_idle;

            extern fn wl_event_loop_get_fd(loop: *EventLoop) c_int;
            pub const getFd = wl_event_loop_get_fd;

            extern fn wl_event_loop_add_destroy_listener(loop: *EventLoop, listener: *Listener(*EventLoop)) void;
            pub const addDestroyListener = wl_event_loop_add_destroy_listener;

            //extern fn wl_event_loop_get_destroy_listener(loop: *EventLoop, notify: @TypeOf(Listener(*EventLoop).notify)) ?*Listener;
            //pub const getDestroyListener = wl_event_loop_get_destroy_listener;
        };

        pub const EventSource = opaque {
            extern fn wl_event_source_remove(source: *EventSource) c_int;
            pub fn remove(source: *EventSource) void {
                if (wl_event_source_remove(source) != 0) unreachable;
            }

            extern fn wl_event_source_check(source: *EventSource) void;
            pub const check = wl_event_source_check;

            extern fn wl_event_source_fd_update(source: *EventSource, mask: u32) c_int;
            pub fn fdUpdate(source: *EventSource, mask: EventMask) !void {
                const rc = wl_event_source_fd_update(source, @bitCast(mask));
                switch (posix.errno(rc)) {
                    .SUCCESS => return,
                    // TODO
                    else => |err| return posix.unexpectedErrno(err),
                }
            }

            extern fn wl_event_source_timer_update(source: *EventSource, ms_delay: c_int) c_int;
            pub fn timerUpdate(source: *EventSource, ms_delay: c_int) !void {
                const rc = wl_event_source_timer_update(source, ms_delay);
                switch (posix.errno(rc)) {
                    .SUCCESS => return,
                    // TODO
                    else => |err| return posix.unexpectedErrno(err),
                }
            }
        };

        pub const shm = struct {
            pub const Buffer = opaque {
                extern fn wl_shm_buffer_get(resource: *Resource) ?*shm.Buffer;
                pub const get = wl_shm_buffer_get;

                extern fn wl_shm_buffer_begin_access(buffer: *shm.Buffer) void;
                pub const beginAccess = wl_shm_buffer_begin_access;

                extern fn wl_shm_buffer_end_access(buffer: *shm.Buffer) void;
                pub const endAccess = wl_shm_buffer_end_access;

                extern fn wl_shm_buffer_get_data(buffer: *shm.Buffer) ?*anyopaque;
                pub const getData = wl_shm_buffer_get_data;

                extern fn wl_shm_buffer_get_format(buffer: *shm.Buffer) u32;
                pub const getFormat = wl_shm_buffer_get_format;

                extern fn wl_shm_buffer_get_height(buffer: *shm.Buffer) i32;
                pub const getHeight = wl_shm_buffer_get_height;

                extern fn wl_shm_buffer_get_width(buffer: *shm.Buffer) i32;
                pub const getWidth = wl_shm_buffer_get_width;

                extern fn wl_shm_buffer_get_stride(buffer: *shm.Buffer) i32;
                pub const getStride = wl_shm_buffer_get_stride;

                extern fn wl_shm_buffer_ref_pool(buffer: *shm.Buffer) *Pool;
                pub const refPool = wl_shm_buffer_ref_pool;
            };

            pub const Pool = opaque {
                extern fn wl_shm_pool_unref(pool: *Pool) void;
                pub const unref = wl_shm_pool_unref;
            };
        };
        pub const Display = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.display.interface;
            pub const Error = common.wl.display.Error;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Display {
                return @ptrCast(try server.wl.Resource.create(_client, Display, _version, _id));
            }
            pub fn destroy(_display: *Display) void {
                return @as(*server.wl.Resource, @ptrCast(_display)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Display {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_display: *Display) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_display)).getLink();
            }
            pub fn getClient(_display: *Display) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_display)).getClient();
            }
            pub fn getId(_display: *Display) u32 {
                return @as(*server.wl.Resource, @ptrCast(_display)).getId();
            }
            pub fn getVersion(_display: *Display) u32 {
                return @as(*server.wl.Resource, @ptrCast(_display)).getVersion();
            }
            pub fn postNoMemory(_display: *Display) void {
                return @as(*server.wl.Resource, @ptrCast(_display)).postNoMemory();
            }
            pub fn getUserData(_display: *Display) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_display)).getUserData();
            }
            pub fn postError(_display: *Display, _err: Error, _message: [*:0]const u8) void {
                return @as(*server.wl.Resource, @ptrCast(_display)).postError(@intCast(@intFromEnum(_err)), _message);
            }
            pub const Request = union(enum) {
                sync: struct {
                    callback: u32,
                },
                get_registry: struct {
                    registry: u32,
                },
            };
            pub inline fn setHandler(
                _display: *Display,
                comptime T: type,
                handle_request: *const fn (_display: *Display, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_display: *Display, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_display);
                _resource.setDispatcher(
                    common.Dispatcher(Display, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Display, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendError(_display: *Display, _object_id: *common.Object, _code: u32, _message: [*:0]const u8) void {
                const _resource: *server.wl.Resource = @ptrCast(_display);
                var _args = [_]common.Argument{
                    .{ .o = @ptrCast(_object_id) },
                    .{ .u = _code },
                    .{ .s = _message },
                };
                _resource.postEvent(0, &_args);
            }
            pub fn sendDeleteId(_display: *Display, _id: u32) void {
                const _resource: *server.wl.Resource = @ptrCast(_display);
                var _args = [_]common.Argument{
                    .{ .u = _id },
                };
                _resource.postEvent(1, &_args);
            }
        };
        pub const Registry = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.registry.interface;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Registry {
                return @ptrCast(try server.wl.Resource.create(_client, Registry, _version, _id));
            }
            pub fn destroy(_registry: *Registry) void {
                return @as(*server.wl.Resource, @ptrCast(_registry)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Registry {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_registry: *Registry) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_registry)).getLink();
            }
            pub fn getClient(_registry: *Registry) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_registry)).getClient();
            }
            pub fn getId(_registry: *Registry) u32 {
                return @as(*server.wl.Resource, @ptrCast(_registry)).getId();
            }
            pub fn getVersion(_registry: *Registry) u32 {
                return @as(*server.wl.Resource, @ptrCast(_registry)).getVersion();
            }
            pub fn postNoMemory(_registry: *Registry) void {
                return @as(*server.wl.Resource, @ptrCast(_registry)).postNoMemory();
            }
            pub fn getUserData(_registry: *Registry) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_registry)).getUserData();
            }
            pub const Request = union(enum) {
                bind: struct {
                    name: u32,
                    interface_name: [*:0]const u8,
                    version: u32,
                    id: u32,
                },
            };
            pub inline fn setHandler(
                _registry: *Registry,
                comptime T: type,
                handle_request: *const fn (_registry: *Registry, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_registry: *Registry, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_registry);
                _resource.setDispatcher(
                    common.Dispatcher(Registry, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Registry, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendGlobal(_registry: *Registry, _name: u32, _interface: [*:0]const u8, _version: u32) void {
                const _resource: *server.wl.Resource = @ptrCast(_registry);
                var _args = [_]common.Argument{
                    .{ .u = _name },
                    .{ .s = _interface },
                    .{ .u = _version },
                };
                _resource.postEvent(0, &_args);
            }
            pub fn sendGlobalRemove(_registry: *Registry, _name: u32) void {
                const _resource: *server.wl.Resource = @ptrCast(_registry);
                var _args = [_]common.Argument{
                    .{ .u = _name },
                };
                _resource.postEvent(1, &_args);
            }
        };
        pub const Callback = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.callback.interface;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Callback {
                return @ptrCast(try server.wl.Resource.create(_client, Callback, _version, _id));
            }
            pub fn destroy(_callback: *Callback) void {
                return @as(*server.wl.Resource, @ptrCast(_callback)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Callback {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_callback: *Callback) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_callback)).getLink();
            }
            pub fn getClient(_callback: *Callback) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_callback)).getClient();
            }
            pub fn getId(_callback: *Callback) u32 {
                return @as(*server.wl.Resource, @ptrCast(_callback)).getId();
            }
            pub fn getVersion(_callback: *Callback) u32 {
                return @as(*server.wl.Resource, @ptrCast(_callback)).getVersion();
            }
            pub fn postNoMemory(_callback: *Callback) void {
                return @as(*server.wl.Resource, @ptrCast(_callback)).postNoMemory();
            }
            pub fn getUserData(_callback: *Callback) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_callback)).getUserData();
            }
            pub inline fn setHandler(
                _callback: *Callback,
                comptime T: type,
                comptime handle_destroy: ?fn (_callback: *Callback, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_callback);
                _resource.setDispatcher(
                    null,
                    null,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Callback, @ptrCast(__resource)),
                                @as(?*anyopaque, @ptrFromInt(@intFromPtr(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn destroySendDone(_callback: *Callback, _callback_data: u32) void {
                const _resource: *server.wl.Resource = @ptrCast(_callback);
                var _args = [_]common.Argument{
                    .{ .u = _callback_data },
                };
                _resource.postEvent(0, &_args);
                _resource.destroy();
            }
        };
        pub const Buffer = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.buffer.interface;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Buffer {
                return @ptrCast(try server.wl.Resource.create(_client, Buffer, _version, _id));
            }
            pub fn destroy(_buffer: *Buffer) void {
                return @as(*server.wl.Resource, @ptrCast(_buffer)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Buffer {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_buffer: *Buffer) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_buffer)).getLink();
            }
            pub fn getClient(_buffer: *Buffer) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_buffer)).getClient();
            }
            pub fn getId(_buffer: *Buffer) u32 {
                return @as(*server.wl.Resource, @ptrCast(_buffer)).getId();
            }
            pub fn getVersion(_buffer: *Buffer) u32 {
                return @as(*server.wl.Resource, @ptrCast(_buffer)).getVersion();
            }
            pub fn postNoMemory(_buffer: *Buffer) void {
                return @as(*server.wl.Resource, @ptrCast(_buffer)).postNoMemory();
            }
            pub fn getUserData(_buffer: *Buffer) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_buffer)).getUserData();
            }
            pub const Request = union(enum) {
                destroy: void,
            };
            pub inline fn setHandler(
                _buffer: *Buffer,
                comptime T: type,
                handle_request: *const fn (_buffer: *Buffer, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_buffer: *Buffer, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_buffer);
                _resource.setDispatcher(
                    common.Dispatcher(Buffer, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Buffer, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendRelease(_buffer: *Buffer) void {
                const _resource: *server.wl.Resource = @ptrCast(_buffer);
                _resource.postEvent(0, null);
            }
        };
        pub const Compositor = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.compositor.interface;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Compositor {
                return @ptrCast(try server.wl.Resource.create(_client, Compositor, _version, _id));
            }
            pub fn destroy(_compositor: *Compositor) void {
                return @as(*server.wl.Resource, @ptrCast(_compositor)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Compositor {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_compositor: *Compositor) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_compositor)).getLink();
            }
            pub fn getClient(_compositor: *Compositor) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_compositor)).getClient();
            }
            pub fn getId(_compositor: *Compositor) u32 {
                return @as(*server.wl.Resource, @ptrCast(_compositor)).getId();
            }
            pub fn getVersion(_compositor: *Compositor) u32 {
                return @as(*server.wl.Resource, @ptrCast(_compositor)).getVersion();
            }
            pub fn postNoMemory(_compositor: *Compositor) void {
                return @as(*server.wl.Resource, @ptrCast(_compositor)).postNoMemory();
            }
            pub fn getUserData(_compositor: *Compositor) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_compositor)).getUserData();
            }
            pub const Request = union(enum) {
                create_surface: struct {
                    id: u32,
                },
                create_region: struct {
                    id: u32,
                },
            };
            pub inline fn setHandler(
                _compositor: *Compositor,
                comptime T: type,
                handle_request: *const fn (_compositor: *Compositor, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_compositor: *Compositor, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_compositor);
                _resource.setDispatcher(
                    common.Dispatcher(Compositor, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Compositor, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
        };
        pub const Surface = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.surface.interface;
            pub const Error = common.wl.surface.Error;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Surface {
                return @ptrCast(try server.wl.Resource.create(_client, Surface, _version, _id));
            }
            pub fn destroy(_surface: *Surface) void {
                return @as(*server.wl.Resource, @ptrCast(_surface)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Surface {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_surface: *Surface) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_surface)).getLink();
            }
            pub fn getClient(_surface: *Surface) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_surface)).getClient();
            }
            pub fn getId(_surface: *Surface) u32 {
                return @as(*server.wl.Resource, @ptrCast(_surface)).getId();
            }
            pub fn getVersion(_surface: *Surface) u32 {
                return @as(*server.wl.Resource, @ptrCast(_surface)).getVersion();
            }
            pub fn postNoMemory(_surface: *Surface) void {
                return @as(*server.wl.Resource, @ptrCast(_surface)).postNoMemory();
            }
            pub fn getUserData(_surface: *Surface) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_surface)).getUserData();
            }
            pub fn postError(_surface: *Surface, _err: Error, _message: [*:0]const u8) void {
                return @as(*server.wl.Resource, @ptrCast(_surface)).postError(@intCast(@intFromEnum(_err)), _message);
            }
            pub const Request = union(enum) {
                destroy: void,
                attach: struct {
                    buffer: ?*server.wl.Buffer,
                    x: i32,
                    y: i32,
                },
                damage: struct {
                    x: i32,
                    y: i32,
                    width: i32,
                    height: i32,
                },
                frame: struct {
                    callback: u32,
                },
                set_opaque_region: struct {
                    region: ?*server.wl.Region,
                },
                set_input_region: struct {
                    region: ?*server.wl.Region,
                },
                commit: void,
                set_buffer_transform: struct {
                    transform: common.wl.output.Transform,
                },
                set_buffer_scale: struct {
                    scale: i32,
                },
                damage_buffer: struct {
                    x: i32,
                    y: i32,
                    width: i32,
                    height: i32,
                },
                offset: struct {
                    x: i32,
                    y: i32,
                },
            };
            pub inline fn setHandler(
                _surface: *Surface,
                comptime T: type,
                handle_request: *const fn (_surface: *Surface, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_surface: *Surface, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_surface);
                _resource.setDispatcher(
                    common.Dispatcher(Surface, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Surface, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendEnter(_surface: *Surface, _output: *server.wl.Output) void {
                const _resource: *server.wl.Resource = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .o = @ptrCast(_output) },
                };
                _resource.postEvent(0, &_args);
            }
            pub fn sendLeave(_surface: *Surface, _output: *server.wl.Output) void {
                const _resource: *server.wl.Resource = @ptrCast(_surface);
                var _args = [_]common.Argument{
                    .{ .o = @ptrCast(_output) },
                };
                _resource.postEvent(1, &_args);
            }
        };
        pub const Region = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.region.interface;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Region {
                return @ptrCast(try server.wl.Resource.create(_client, Region, _version, _id));
            }
            pub fn destroy(_region: *Region) void {
                return @as(*server.wl.Resource, @ptrCast(_region)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Region {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_region: *Region) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_region)).getLink();
            }
            pub fn getClient(_region: *Region) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_region)).getClient();
            }
            pub fn getId(_region: *Region) u32 {
                return @as(*server.wl.Resource, @ptrCast(_region)).getId();
            }
            pub fn getVersion(_region: *Region) u32 {
                return @as(*server.wl.Resource, @ptrCast(_region)).getVersion();
            }
            pub fn postNoMemory(_region: *Region) void {
                return @as(*server.wl.Resource, @ptrCast(_region)).postNoMemory();
            }
            pub fn getUserData(_region: *Region) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_region)).getUserData();
            }
            pub const Request = union(enum) {
                destroy: void,
                add: struct {
                    x: i32,
                    y: i32,
                    width: i32,
                    height: i32,
                },
                subtract: struct {
                    x: i32,
                    y: i32,
                    width: i32,
                    height: i32,
                },
            };
            pub inline fn setHandler(
                _region: *Region,
                comptime T: type,
                handle_request: *const fn (_region: *Region, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_region: *Region, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_region);
                _resource.setDispatcher(
                    common.Dispatcher(Region, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Region, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
        };
        pub const Shm = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.shm.interface;
            pub const Error = common.wl.shm.Error;
            pub const Format = common.wl.shm.Format;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Shm {
                return @ptrCast(try server.wl.Resource.create(_client, Shm, _version, _id));
            }
            pub fn destroy(_shm: *Shm) void {
                return @as(*server.wl.Resource, @ptrCast(_shm)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Shm {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_shm: *Shm) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_shm)).getLink();
            }
            pub fn getClient(_shm: *Shm) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_shm)).getClient();
            }
            pub fn getId(_shm: *Shm) u32 {
                return @as(*server.wl.Resource, @ptrCast(_shm)).getId();
            }
            pub fn getVersion(_shm: *Shm) u32 {
                return @as(*server.wl.Resource, @ptrCast(_shm)).getVersion();
            }
            pub fn postNoMemory(_shm: *Shm) void {
                return @as(*server.wl.Resource, @ptrCast(_shm)).postNoMemory();
            }
            pub fn getUserData(_shm: *Shm) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_shm)).getUserData();
            }
            pub fn postError(_shm: *Shm, _err: Error, _message: [*:0]const u8) void {
                return @as(*server.wl.Resource, @ptrCast(_shm)).postError(@intCast(@intFromEnum(_err)), _message);
            }
            pub const Request = union(enum) {
                create_pool: struct {
                    id: u32,
                    fd: i32,
                    size: i32,
                },
            };
            pub inline fn setHandler(
                _shm: *Shm,
                comptime T: type,
                handle_request: *const fn (_shm: *Shm, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_shm: *Shm, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_shm);
                _resource.setDispatcher(
                    common.Dispatcher(Shm, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Shm, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendFormat(_shm: *Shm, _format: Format) void {
                const _resource: *server.wl.Resource = @ptrCast(_shm);
                var _args = [_]common.Argument{
                    .{ .u = switch (@typeInfo(Format)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_format))),
                        .@"struct" => @bitCast(_format),
                        else => unreachable,
                    } },
                };
                _resource.postEvent(0, &_args);
            }
        };
        pub const ShmPool = opaque {
            pub const generated_version = 1;
            pub const interface = &common.wl.shm_pool.interface;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*ShmPool {
                return @ptrCast(try server.wl.Resource.create(_client, ShmPool, _version, _id));
            }
            pub fn destroy(_shm_pool: *ShmPool) void {
                return @as(*server.wl.Resource, @ptrCast(_shm_pool)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *ShmPool {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_shm_pool: *ShmPool) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_shm_pool)).getLink();
            }
            pub fn getClient(_shm_pool: *ShmPool) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_shm_pool)).getClient();
            }
            pub fn getId(_shm_pool: *ShmPool) u32 {
                return @as(*server.wl.Resource, @ptrCast(_shm_pool)).getId();
            }
            pub fn getVersion(_shm_pool: *ShmPool) u32 {
                return @as(*server.wl.Resource, @ptrCast(_shm_pool)).getVersion();
            }
            pub fn postNoMemory(_shm_pool: *ShmPool) void {
                return @as(*server.wl.Resource, @ptrCast(_shm_pool)).postNoMemory();
            }
            pub fn getUserData(_shm_pool: *ShmPool) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_shm_pool)).getUserData();
            }
            pub const Request = union(enum) {
                create_buffer: struct {
                    id: u32,
                    offset: i32,
                    width: i32,
                    height: i32,
                    stride: i32,
                    format: common.wl.shm.Format,
                },
                destroy: void,
                resize: struct {
                    size: i32,
                },
            };
            pub inline fn setHandler(
                _shm_pool: *ShmPool,
                comptime T: type,
                handle_request: *const fn (_shm_pool: *ShmPool, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_shm_pool: *ShmPool, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_shm_pool);
                _resource.setDispatcher(
                    common.Dispatcher(ShmPool, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*ShmPool, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
        };
        pub const Seat = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.seat.interface;
            pub const Capability = common.wl.seat.Capability;
            pub const Error = common.wl.seat.Error;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Seat {
                return @ptrCast(try server.wl.Resource.create(_client, Seat, _version, _id));
            }
            pub fn destroy(_seat: *Seat) void {
                return @as(*server.wl.Resource, @ptrCast(_seat)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Seat {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_seat: *Seat) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_seat)).getLink();
            }
            pub fn getClient(_seat: *Seat) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_seat)).getClient();
            }
            pub fn getId(_seat: *Seat) u32 {
                return @as(*server.wl.Resource, @ptrCast(_seat)).getId();
            }
            pub fn getVersion(_seat: *Seat) u32 {
                return @as(*server.wl.Resource, @ptrCast(_seat)).getVersion();
            }
            pub fn postNoMemory(_seat: *Seat) void {
                return @as(*server.wl.Resource, @ptrCast(_seat)).postNoMemory();
            }
            pub fn getUserData(_seat: *Seat) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_seat)).getUserData();
            }
            pub fn postError(_seat: *Seat, _err: Error, _message: [*:0]const u8) void {
                return @as(*server.wl.Resource, @ptrCast(_seat)).postError(@intCast(@intFromEnum(_err)), _message);
            }
            pub const Request = union(enum) {
                get_pointer: struct {
                    id: u32,
                },
                get_keyboard: struct {
                    id: u32,
                },
                get_touch: struct {
                    id: u32,
                },
                release: void,
            };
            pub inline fn setHandler(
                _seat: *Seat,
                comptime T: type,
                handle_request: *const fn (_seat: *Seat, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_seat: *Seat, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_seat);
                _resource.setDispatcher(
                    common.Dispatcher(Seat, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Seat, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendCapabilities(_seat: *Seat, _capabilities: Capability) void {
                const _resource: *server.wl.Resource = @ptrCast(_seat);
                var _args = [_]common.Argument{
                    .{ .u = switch (@typeInfo(Capability)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_capabilities))),
                        .@"struct" => @bitCast(_capabilities),
                        else => unreachable,
                    } },
                };
                _resource.postEvent(0, &_args);
            }
            pub fn sendName(_seat: *Seat, _name: [*:0]const u8) void {
                const _resource: *server.wl.Resource = @ptrCast(_seat);
                var _args = [_]common.Argument{
                    .{ .s = _name },
                };
                _resource.postEvent(1, &_args);
            }
        };
        pub const Pointer = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.pointer.interface;
            pub const Error = common.wl.pointer.Error;
            pub const ButtonState = common.wl.pointer.ButtonState;
            pub const Axis = common.wl.pointer.Axis;
            pub const AxisSource = common.wl.pointer.AxisSource;
            pub const AxisRelativeDirection = common.wl.pointer.AxisRelativeDirection;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Pointer {
                return @ptrCast(try server.wl.Resource.create(_client, Pointer, _version, _id));
            }
            pub fn destroy(_pointer: *Pointer) void {
                return @as(*server.wl.Resource, @ptrCast(_pointer)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Pointer {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_pointer: *Pointer) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_pointer)).getLink();
            }
            pub fn getClient(_pointer: *Pointer) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_pointer)).getClient();
            }
            pub fn getId(_pointer: *Pointer) u32 {
                return @as(*server.wl.Resource, @ptrCast(_pointer)).getId();
            }
            pub fn getVersion(_pointer: *Pointer) u32 {
                return @as(*server.wl.Resource, @ptrCast(_pointer)).getVersion();
            }
            pub fn postNoMemory(_pointer: *Pointer) void {
                return @as(*server.wl.Resource, @ptrCast(_pointer)).postNoMemory();
            }
            pub fn getUserData(_pointer: *Pointer) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_pointer)).getUserData();
            }
            pub fn postError(_pointer: *Pointer, _err: Error, _message: [*:0]const u8) void {
                return @as(*server.wl.Resource, @ptrCast(_pointer)).postError(@intCast(@intFromEnum(_err)), _message);
            }
            pub const Request = union(enum) {
                set_cursor: struct {
                    serial: u32,
                    surface: ?*server.wl.Surface,
                    hotspot_x: i32,
                    hotspot_y: i32,
                },
                release: void,
            };
            pub inline fn setHandler(
                _pointer: *Pointer,
                comptime T: type,
                handle_request: *const fn (_pointer: *Pointer, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_pointer: *Pointer, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                _resource.setDispatcher(
                    common.Dispatcher(Pointer, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Pointer, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendEnter(_pointer: *Pointer, _serial: u32, _surface: *server.wl.Surface, _surface_x: common.Fixed, _surface_y: common.Fixed) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .o = @ptrCast(_surface) },
                    .{ .f = _surface_x },
                    .{ .f = _surface_y },
                };
                _resource.postEvent(0, &_args);
            }
            pub fn sendLeave(_pointer: *Pointer, _serial: u32, _surface: *server.wl.Surface) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .o = @ptrCast(_surface) },
                };
                _resource.postEvent(1, &_args);
            }
            pub fn sendMotion(_pointer: *Pointer, _time: u32, _surface_x: common.Fixed, _surface_y: common.Fixed) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = _time },
                    .{ .f = _surface_x },
                    .{ .f = _surface_y },
                };
                _resource.postEvent(2, &_args);
            }
            pub fn sendButton(_pointer: *Pointer, _serial: u32, _time: u32, _button: u32, _state: ButtonState) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .u = _time },
                    .{ .u = _button },
                    .{ .u = switch (@typeInfo(ButtonState)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_state))),
                        .@"struct" => @bitCast(_state),
                        else => unreachable,
                    } },
                };
                _resource.postEvent(3, &_args);
            }
            pub fn sendAxis(_pointer: *Pointer, _time: u32, _axis: Axis, _value: common.Fixed) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = _time },
                    .{ .u = switch (@typeInfo(Axis)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_axis))),
                        .@"struct" => @bitCast(_axis),
                        else => unreachable,
                    } },
                    .{ .f = _value },
                };
                _resource.postEvent(4, &_args);
            }
            pub fn sendFrame(_pointer: *Pointer) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                _resource.postEvent(5, null);
            }
            pub fn sendAxisSource(_pointer: *Pointer, _axis_source: AxisSource) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = switch (@typeInfo(AxisSource)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_axis_source))),
                        .@"struct" => @bitCast(_axis_source),
                        else => unreachable,
                    } },
                };
                _resource.postEvent(6, &_args);
            }
            pub fn sendAxisStop(_pointer: *Pointer, _time: u32, _axis: Axis) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = _time },
                    .{ .u = switch (@typeInfo(Axis)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_axis))),
                        .@"struct" => @bitCast(_axis),
                        else => unreachable,
                    } },
                };
                _resource.postEvent(7, &_args);
            }
            pub fn sendAxisDiscrete(_pointer: *Pointer, _axis: Axis, _discrete: i32) void {
                const _resource: *server.wl.Resource = @ptrCast(_pointer);
                var _args = [_]common.Argument{
                    .{ .u = switch (@typeInfo(Axis)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_axis))),
                        .@"struct" => @bitCast(_axis),
                        else => unreachable,
                    } },
                    .{ .i = _discrete },
                };
                _resource.postEvent(8, &_args);
            }
        };
        pub const Keyboard = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.keyboard.interface;
            pub const KeymapFormat = common.wl.keyboard.KeymapFormat;
            pub const KeyState = common.wl.keyboard.KeyState;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Keyboard {
                return @ptrCast(try server.wl.Resource.create(_client, Keyboard, _version, _id));
            }
            pub fn destroy(_keyboard: *Keyboard) void {
                return @as(*server.wl.Resource, @ptrCast(_keyboard)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Keyboard {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_keyboard: *Keyboard) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_keyboard)).getLink();
            }
            pub fn getClient(_keyboard: *Keyboard) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_keyboard)).getClient();
            }
            pub fn getId(_keyboard: *Keyboard) u32 {
                return @as(*server.wl.Resource, @ptrCast(_keyboard)).getId();
            }
            pub fn getVersion(_keyboard: *Keyboard) u32 {
                return @as(*server.wl.Resource, @ptrCast(_keyboard)).getVersion();
            }
            pub fn postNoMemory(_keyboard: *Keyboard) void {
                return @as(*server.wl.Resource, @ptrCast(_keyboard)).postNoMemory();
            }
            pub fn getUserData(_keyboard: *Keyboard) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_keyboard)).getUserData();
            }
            pub const Request = union(enum) {
                release: void,
            };
            pub inline fn setHandler(
                _keyboard: *Keyboard,
                comptime T: type,
                handle_request: *const fn (_keyboard: *Keyboard, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_keyboard: *Keyboard, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_keyboard);
                _resource.setDispatcher(
                    common.Dispatcher(Keyboard, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Keyboard, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendKeymap(_keyboard: *Keyboard, _format: KeymapFormat, _fd: i32, _size: u32) void {
                const _resource: *server.wl.Resource = @ptrCast(_keyboard);
                var _args = [_]common.Argument{
                    .{ .u = switch (@typeInfo(KeymapFormat)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_format))),
                        .@"struct" => @bitCast(_format),
                        else => unreachable,
                    } },
                    .{ .h = _fd },
                    .{ .u = _size },
                };
                _resource.postEvent(0, &_args);
            }
            pub fn sendEnter(_keyboard: *Keyboard, _serial: u32, _surface: *server.wl.Surface, _keys: *common.Array) void {
                const _resource: *server.wl.Resource = @ptrCast(_keyboard);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .o = @ptrCast(_surface) },
                    .{ .a = _keys },
                };
                _resource.postEvent(1, &_args);
            }
            pub fn sendLeave(_keyboard: *Keyboard, _serial: u32, _surface: *server.wl.Surface) void {
                const _resource: *server.wl.Resource = @ptrCast(_keyboard);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .o = @ptrCast(_surface) },
                };
                _resource.postEvent(2, &_args);
            }
            pub fn sendKey(_keyboard: *Keyboard, _serial: u32, _time: u32, _key: u32, _state: KeyState) void {
                const _resource: *server.wl.Resource = @ptrCast(_keyboard);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .u = _time },
                    .{ .u = _key },
                    .{ .u = switch (@typeInfo(KeyState)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_state))),
                        .@"struct" => @bitCast(_state),
                        else => unreachable,
                    } },
                };
                _resource.postEvent(3, &_args);
            }
            pub fn sendModifiers(_keyboard: *Keyboard, _serial: u32, _mods_depressed: u32, _mods_latched: u32, _mods_locked: u32, _group: u32) void {
                const _resource: *server.wl.Resource = @ptrCast(_keyboard);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .u = _mods_depressed },
                    .{ .u = _mods_latched },
                    .{ .u = _mods_locked },
                    .{ .u = _group },
                };
                _resource.postEvent(4, &_args);
            }
            pub fn sendRepeatInfo(_keyboard: *Keyboard, _rate: i32, _delay: i32) void {
                const _resource: *server.wl.Resource = @ptrCast(_keyboard);
                var _args = [_]common.Argument{
                    .{ .i = _rate },
                    .{ .i = _delay },
                };
                _resource.postEvent(5, &_args);
            }
        };
        pub const Touch = opaque {
            pub const generated_version = 5;
            pub const interface = &common.wl.touch.interface;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Touch {
                return @ptrCast(try server.wl.Resource.create(_client, Touch, _version, _id));
            }
            pub fn destroy(_touch: *Touch) void {
                return @as(*server.wl.Resource, @ptrCast(_touch)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Touch {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_touch: *Touch) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_touch)).getLink();
            }
            pub fn getClient(_touch: *Touch) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_touch)).getClient();
            }
            pub fn getId(_touch: *Touch) u32 {
                return @as(*server.wl.Resource, @ptrCast(_touch)).getId();
            }
            pub fn getVersion(_touch: *Touch) u32 {
                return @as(*server.wl.Resource, @ptrCast(_touch)).getVersion();
            }
            pub fn postNoMemory(_touch: *Touch) void {
                return @as(*server.wl.Resource, @ptrCast(_touch)).postNoMemory();
            }
            pub fn getUserData(_touch: *Touch) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_touch)).getUserData();
            }
            pub const Request = union(enum) {
                release: void,
            };
            pub inline fn setHandler(
                _touch: *Touch,
                comptime T: type,
                handle_request: *const fn (_touch: *Touch, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_touch: *Touch, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_touch);
                _resource.setDispatcher(
                    common.Dispatcher(Touch, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Touch, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendDown(_touch: *Touch, _serial: u32, _time: u32, _surface: *server.wl.Surface, _id: i32, _x: common.Fixed, _y: common.Fixed) void {
                const _resource: *server.wl.Resource = @ptrCast(_touch);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .u = _time },
                    .{ .o = @ptrCast(_surface) },
                    .{ .i = _id },
                    .{ .f = _x },
                    .{ .f = _y },
                };
                _resource.postEvent(0, &_args);
            }
            pub fn sendUp(_touch: *Touch, _serial: u32, _time: u32, _id: i32) void {
                const _resource: *server.wl.Resource = @ptrCast(_touch);
                var _args = [_]common.Argument{
                    .{ .u = _serial },
                    .{ .u = _time },
                    .{ .i = _id },
                };
                _resource.postEvent(1, &_args);
            }
            pub fn sendMotion(_touch: *Touch, _time: u32, _id: i32, _x: common.Fixed, _y: common.Fixed) void {
                const _resource: *server.wl.Resource = @ptrCast(_touch);
                var _args = [_]common.Argument{
                    .{ .u = _time },
                    .{ .i = _id },
                    .{ .f = _x },
                    .{ .f = _y },
                };
                _resource.postEvent(2, &_args);
            }
            pub fn sendFrame(_touch: *Touch) void {
                const _resource: *server.wl.Resource = @ptrCast(_touch);
                _resource.postEvent(3, null);
            }
            pub fn sendCancel(_touch: *Touch) void {
                const _resource: *server.wl.Resource = @ptrCast(_touch);
                _resource.postEvent(4, null);
            }
        };
        pub const Output = opaque {
            pub const generated_version = 4;
            pub const interface = &common.wl.output.interface;
            pub const Subpixel = common.wl.output.Subpixel;
            pub const Transform = common.wl.output.Transform;
            pub const Mode = common.wl.output.Mode;
            pub fn create(_client: *server.wl.Client, _version: u32, _id: u32) !*Output {
                return @ptrCast(try server.wl.Resource.create(_client, Output, _version, _id));
            }
            pub fn destroy(_output: *Output) void {
                return @as(*server.wl.Resource, @ptrCast(_output)).destroy();
            }
            pub fn fromLink(_link: *server.wl.list.Link) *Output {
                return @ptrCast(server.wl.Resource.fromLink(_link));
            }
            pub fn getLink(_output: *Output) *server.wl.list.Link {
                return @as(*server.wl.Resource, @ptrCast(_output)).getLink();
            }
            pub fn getClient(_output: *Output) *server.wl.Client {
                return @as(*server.wl.Resource, @ptrCast(_output)).getClient();
            }
            pub fn getId(_output: *Output) u32 {
                return @as(*server.wl.Resource, @ptrCast(_output)).getId();
            }
            pub fn getVersion(_output: *Output) u32 {
                return @as(*server.wl.Resource, @ptrCast(_output)).getVersion();
            }
            pub fn postNoMemory(_output: *Output) void {
                return @as(*server.wl.Resource, @ptrCast(_output)).postNoMemory();
            }
            pub fn getUserData(_output: *Output) ?*anyopaque {
                return @as(*server.wl.Resource, @ptrCast(_output)).getUserData();
            }
            pub const Request = union(enum) {
                release: void,
            };
            pub inline fn setHandler(
                _output: *Output,
                comptime T: type,
                handle_request: *const fn (_output: *Output, request: Request, data: T) void,
                comptime handle_destroy: ?fn (_output: *Output, data: T) void,
                _data: T,
            ) void {
                const _resource: *server.wl.Resource = @ptrCast(_output);
                _resource.setDispatcher(
                    common.Dispatcher(Output, T).dispatcher,
                    handle_request,
                    @ptrFromInt(@intFromPtr(_data)),
                    if (handle_destroy) |_handler| struct {
                        fn _wrapper(__resource: *server.wl.Resource) callconv(.c) void {
                            @call(.always_inline, _handler, .{
                                @as(*Output, @ptrCast(__resource)),
                                @as(T, @ptrCast(@alignCast(__resource.getUserData()))),
                            });
                        }
                    }._wrapper else null,
                );
            }
            pub fn sendGeometry(_output: *Output, _x: i32, _y: i32, _physical_width: i32, _physical_height: i32, _subpixel: Subpixel, _make: [*:0]const u8, _model: [*:0]const u8, _transform: Transform) void {
                const _resource: *server.wl.Resource = @ptrCast(_output);
                var _args = [_]common.Argument{
                    .{ .i = _x },
                    .{ .i = _y },
                    .{ .i = _physical_width },
                    .{ .i = _physical_height },
                    .{ .i = switch (@typeInfo(Subpixel)) {
                        .@"enum" => @as(i32, @intCast(@intFromEnum(_subpixel))),
                        .@"struct" => @bitCast(_subpixel),
                        else => unreachable,
                    } },
                    .{ .s = _make },
                    .{ .s = _model },
                    .{ .i = switch (@typeInfo(Transform)) {
                        .@"enum" => @as(i32, @intCast(@intFromEnum(_transform))),
                        .@"struct" => @bitCast(_transform),
                        else => unreachable,
                    } },
                };
                _resource.postEvent(0, &_args);
            }
            pub fn sendMode(_output: *Output, _flags: Mode, _width: i32, _height: i32, _refresh: i32) void {
                const _resource: *server.wl.Resource = @ptrCast(_output);
                var _args = [_]common.Argument{
                    .{ .u = switch (@typeInfo(Mode)) {
                        .@"enum" => @as(u32, @intCast(@intFromEnum(_flags))),
                        .@"struct" => @bitCast(_flags),
                        else => unreachable,
                    } },
                    .{ .i = _width },
                    .{ .i = _height },
                    .{ .i = _refresh },
                };
                _resource.postEvent(1, &_args);
            }
            pub fn sendDone(_output: *Output) void {
                const _resource: *server.wl.Resource = @ptrCast(_output);
                _resource.postEvent(2, null);
            }
            pub fn sendScale(_output: *Output, _factor: i32) void {
                const _resource: *server.wl.Resource = @ptrCast(_output);
                var _args = [_]common.Argument{
                    .{ .i = _factor },
                };
                _resource.postEvent(3, &_args);
            }
            pub fn sendName(_output: *Output, _name: [*:0]const u8) void {
                const _resource: *server.wl.Resource = @ptrCast(_output);
                var _args = [_]common.Argument{
                    .{ .s = _name },
                };
                _resource.postEvent(4, &_args);
            }
            pub fn sendDescription(_output: *Output, _description: [*:0]const u8) void {
                const _resource: *server.wl.Resource = @ptrCast(_output);
                var _args = [_]common.Argument{
                    .{ .s = _description },
                };
                _resource.postEvent(5, &_args);
            }
        };
    };
};

const common = struct {
    const Object = opaque {};

    const Message = extern struct {
        name: [*:0]const u8,
        signature: [*:0]const u8,
        types: ?[*]const ?*const Interface,
    };

    const Interface = extern struct {
        name: [*:0]const u8,
        version: c_int,
        method_count: c_int,
        methods: ?[*]const Message,
        event_count: c_int,
        events: ?[*]const Message,
    };

    const list = struct {
        pub const Link = extern struct {
            prev: ?*Link,
            next: ?*Link,

            pub fn init(link: *Link) void {
                link.* = .{ .prev = link, .next = link };
            }

            pub fn insert(link: *Link, other: *Link) void {
                other.prev = link;
                other.next = link.next;
                link.next = other;
                other.next.?.prev = other;
            }

            pub fn remove(link: *Link) void {
                link.prev.?.next = link.next;
                link.next.?.prev = link.prev;
                link.* = .{ .prev = null, .next = null };
            }

            pub fn replaceWith(link: *Link, other: *Link) void {
                other.next = link.next;
                other.next.?.prev = other;
                other.prev = link.prev;
                other.prev.?.next = other;

                link.* = .{ .prev = null, .next = null };
            }

            pub fn swapWith(link: *Link, other: *Link) void {
                const old_other_prev = other.prev.?;
                other.remove();

                link.replaceWith(other);

                if (old_other_prev == link) {
                    other.insert(link);
                } else {
                    old_other_prev.insert(link);
                }
            }

            /// private helper that doesn't handle empty lists and assumes that
            /// other is the link of a Head.
            fn insertList(link: *Link, other: *Link) void {
                other.next.?.prev = link;
                other.prev.?.next = link.next;
                link.next.?.prev = other.prev;
                link.next = other.next;

                other.init();
            }
        };

        pub const Direction = enum {
            forward,
            reverse,
        };

        /// This has the same ABI as wl.list.Link/wl_list. If link_field is null, then
        /// T.getLink()/T.fromLink() will be used. This allows for compatiability
        /// with wl.Client and wl.Resource
        pub fn Head(comptime T: type, comptime link_field: ?@Type(.enum_literal)) type {
            return extern struct {
                const Self = @This();

                link: Link,

                pub fn init(head: *Self) void {
                    head.link.init();
                }

                pub fn prepend(head: *Self, elem: *T) void {
                    head.link.insert(linkFromElem(elem));
                }

                pub fn append(head: *Self, elem: *T) void {
                    head.link.prev.?.insert(linkFromElem(elem));
                }

                pub fn prependList(head: *Self, other: *Self) void {
                    if (other.empty()) return;
                    head.link.insertList(&other.link);
                }

                pub fn appendList(head: *Self, other: *Self) void {
                    if (other.empty()) return;
                    head.link.prev.?.insertList(&other.link);
                }

                pub fn first(head: *Self) ?*T {
                    if (head.empty()) {
                        return null;
                    } else {
                        return elemFromLink(head.link.next.?);
                    }
                }

                pub fn last(head: *Self) ?*T {
                    if (head.empty()) {
                        return null;
                    } else {
                        return elemFromLink(head.link.prev.?);
                    }
                }

                pub fn length(head: *const Self) usize {
                    var count: usize = 0;
                    var current = head.link.next.?;
                    while (current != &head.link) : (current = current.next.?) {
                        count += 1;
                    }
                    return count;
                }

                pub fn empty(head: *const Self) bool {
                    return head.link.next == &head.link;
                }

                /// Removal of elements during iteration is illegal
                pub fn Iterator(comptime direction: Direction) type {
                    return struct {
                        head: *Link,
                        current: *Link,

                        pub fn next(it: *@This()) ?*T {
                            it.current = switch (direction) {
                                .forward => it.current.next.?,
                                .reverse => it.current.prev.?,
                            };
                            if (it.current == it.head) return null;
                            return elemFromLink(it.current);
                        }
                    };
                }

                /// Removal of elements during iteration is illegal
                pub fn iterator(head: *Self, comptime direction: Direction) Iterator(direction) {
                    return .{ .head = &head.link, .current = &head.link };
                }

                /// Removal of the current element during iteration is permitted.
                /// Removal of other elements is illegal.
                pub fn SafeIterator(comptime direction: Direction) type {
                    return struct {
                        head: *Link,
                        current: *Link,
                        future: *Link,

                        pub fn next(it: *@This()) ?*T {
                            it.current = it.future;
                            it.future = switch (direction) {
                                .forward => it.future.next.?,
                                .reverse => it.future.prev.?,
                            };
                            if (it.current == it.head) return null;
                            return elemFromLink(it.current);
                        }
                    };
                }

                /// Removal of the current element during iteration is permitted.
                /// Removal of other elements is illegal.
                pub fn safeIterator(head: *Self, comptime direction: Direction) SafeIterator(direction) {
                    return .{
                        .head = &head.link,
                        .current = &head.link,
                        .future = switch (direction) {
                            .forward => head.link.next.?,
                            .reverse => head.link.prev.?,
                        },
                    };
                }

                fn linkFromElem(elem: *T) *Link {
                    if (link_field) |f| {
                        return &@field(elem, @tagName(f));
                    } else {
                        return elem.getLink();
                    }
                }

                fn elemFromLink(link: *Link) *T {
                    if (link_field) |f| {
                        return @fieldParentPtr(@tagName(f), link);
                    } else {
                        return T.fromLink(link);
                    }
                }
            };
        }
    };

    const Array = extern struct {
        size: usize,
        alloc: usize,
        data: ?*anyopaque,

        /// Does not clone memory
        pub fn fromArrayList(comptime T: type, array_list: std.ArrayList(T)) Array {
            return Array{
                .size = array_list.items.len * @sizeOf(T),
                .alloc = array_list.capacity * @sizeOf(T),
                .data = array_list.items.ptr,
            };
        }

        pub fn slice(array: Array, comptime T: type) []align(4) T {
            const data = array.data orelse return &[0]T{};
            // The wire protocol/libwayland only guarantee 32-bit word alignment.
            const ptr: [*]align(4) T = @ptrCast(@alignCast(data));
            return ptr[0..@divExact(array.size, @sizeOf(T))];
        }
    };

    /// A 24.8 signed fixed-point number.
    const Fixed = enum(i32) {
        _,

        pub fn toInt(f: Fixed) i24 {
            return @truncate(@intFromEnum(f) >> 8);
        }

        pub fn fromInt(i: i24) Fixed {
            return @enumFromInt(@as(i32, i) << 8);
        }

        pub fn toDouble(f: Fixed) f64 {
            return @as(f64, @floatFromInt(@intFromEnum(f))) / 256;
        }

        pub fn fromDouble(d: f64) Fixed {
            return @enumFromInt(@as(i32, @intFromFloat(d * 256)));
        }
    };

    const Argument = extern union {
        i: i32,
        u: u32,
        f: Fixed,
        s: ?[*:0]const u8,
        o: ?*Object,
        n: u32,
        a: ?*Array,
        h: i32,
    };

    fn Dispatcher(comptime Obj: type, comptime Data: type) type {
        const client_side = @hasDecl(Obj, "Event");
        const Payload = if (client_side) Obj.Event else Obj.Request;
        return struct {
            fn dispatcher(
                implementation: ?*const anyopaque,
                object: if (client_side) *client.wl.Proxy else *server.wl.Resource,
                opcode: u32,
                _: *const Message,
                args: [*]Argument,
            ) callconv(.c) c_int {
                inline for (@typeInfo(Payload).@"union".fields, 0..) |payload_field, payload_num| {
                    if (payload_num == opcode) {
                        var payload_data: payload_field.type = undefined;
                        if (payload_field.type != void) {
                            inline for (@typeInfo(payload_field.type).@"struct".fields, 0..) |f, i| {
                                switch (@typeInfo(f.type)) {
                                    // signed/unsigned ints, fds, new_ids, bitfield enums
                                    .int, .@"struct" => @field(payload_data, f.name) = @as(f.type, @bitCast(args[i].u)),
                                    // objects, strings, arrays
                                    .pointer, .optional => @field(payload_data, f.name) = @as(f.type, @ptrFromInt(@intFromPtr(args[i].o))),
                                    // non-bitfield enums
                                    .@"enum" => @field(payload_data, f.name) = @as(f.type, @enumFromInt(args[i].i)),
                                    else => unreachable,
                                }
                            }
                        }

                        const HandlerFn = fn (*Obj, Payload, Data) void;
                        @as(*const HandlerFn, @ptrCast(@alignCast(implementation)))(
                            @as(*Obj, @ptrCast(object)),
                            @unionInit(Payload, payload_field.name, payload_data),
                            @as(Data, @ptrFromInt(@intFromPtr(object.getUserData()))),
                        );

                        return 0;
                    }
                }
                unreachable;
            }
        };
    }
    const wl = struct {
        const display = struct {
            const interface: common.Interface = .{
                .name = "wl_display",
                .version = 1,
                .method_count = 2,
                .methods = &.{
                    .{
                        .name = "sync",
                        .signature = "n",
                        .types = &.{
                            &common.wl.callback.interface,
                        },
                    },
                    .{
                        .name = "get_registry",
                        .signature = "n",
                        .types = &.{
                            &common.wl.registry.interface,
                        },
                    },
                },
                .event_count = 2,
                .events = &.{
                    .{
                        .name = "error",
                        .signature = "ous",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "delete_id",
                        .signature = "u",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
            const Error = enum(c_int) {
                invalid_object = 0,
                invalid_method = 1,
                no_memory = 2,
                implementation = 3,
                _,
            };
        };
        const registry = struct {
            const interface: common.Interface = .{
                .name = "wl_registry",
                .version = 1,
                .method_count = 1,
                .methods = &.{
                    .{
                        .name = "bind",
                        .signature = "usun",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                },
                .event_count = 2,
                .events = &.{
                    .{
                        .name = "global",
                        .signature = "usu",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "global_remove",
                        .signature = "u",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
        };
        const callback = struct {
            const interface: common.Interface = .{
                .name = "wl_callback",
                .version = 1,
                .method_count = 0,
                .methods = null,
                .event_count = 1,
                .events = &.{
                    .{
                        .name = "done",
                        .signature = "u",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
        };
        const buffer = struct {
            const interface: common.Interface = .{
                .name = "wl_buffer",
                .version = 1,
                .method_count = 1,
                .methods = &.{
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                },
                .event_count = 1,
                .events = &.{
                    .{
                        .name = "release",
                        .signature = "",
                        .types = null,
                    },
                },
            };
        };
        const compositor = struct {
            const interface: common.Interface = .{
                .name = "wl_compositor",
                .version = 6,
                .method_count = 2,
                .methods = &.{
                    .{
                        .name = "create_surface",
                        .signature = "n",
                        .types = &.{
                            &common.wl.surface.interface,
                        },
                    },
                    .{
                        .name = "create_region",
                        .signature = "n",
                        .types = &.{
                            &common.wl.region.interface,
                        },
                    },
                },
                .event_count = 0,
                .events = null,
            };
        };
        const surface = struct {
            const interface: common.Interface = .{
                .name = "wl_surface",
                .version = 6,
                .method_count = 11,
                .methods = &.{
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "attach",
                        .signature = "?oii",
                        .types = &.{
                            &common.wl.buffer.interface,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "damage",
                        .signature = "iiii",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "frame",
                        .signature = "n",
                        .types = &.{
                            &common.wl.callback.interface,
                        },
                    },
                    .{
                        .name = "set_opaque_region",
                        .signature = "?o",
                        .types = &.{
                            &common.wl.region.interface,
                        },
                    },
                    .{
                        .name = "set_input_region",
                        .signature = "?o",
                        .types = &.{
                            &common.wl.region.interface,
                        },
                    },
                    .{
                        .name = "commit",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "set_buffer_transform",
                        .signature = "2i",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "set_buffer_scale",
                        .signature = "3i",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "damage_buffer",
                        .signature = "4iiii",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "offset",
                        .signature = "5ii",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                },
                .event_count = 4,
                .events = &.{
                    .{
                        .name = "enter",
                        .signature = "o",
                        .types = &.{
                            &common.wl.output.interface,
                        },
                    },
                    .{
                        .name = "leave",
                        .signature = "o",
                        .types = &.{
                            &common.wl.output.interface,
                        },
                    },
                    .{
                        .name = "preferred_buffer_scale",
                        .signature = "6i",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "preferred_buffer_transform",
                        .signature = "6u",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
            const Error = enum(c_int) {
                invalid_scale = 0,
                invalid_transform = 1,
                invalid_size = 2,
                invalid_offset = 3,
                defunct_role_object = 4,
                _,
            };
        };
        const region = struct {
            const interface: common.Interface = .{
                .name = "wl_region",
                .version = 1,
                .method_count = 3,
                .methods = &.{
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "add",
                        .signature = "iiii",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "subtract",
                        .signature = "iiii",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                },
                .event_count = 0,
                .events = null,
            };
        };
        const shm = struct {
            const interface: common.Interface = .{
                .name = "wl_shm",
                .version = 2,
                .method_count = 2,
                .methods = &.{
                    .{
                        .name = "create_pool",
                        .signature = "nhi",
                        .types = &.{
                            &common.wl.shm_pool.interface,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "release",
                        .signature = "2",
                        .types = null,
                    },
                },
                .event_count = 1,
                .events = &.{
                    .{
                        .name = "format",
                        .signature = "u",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
            const Error = enum(c_int) {
                invalid_format = 0,
                invalid_stride = 1,
                invalid_fd = 2,
                _,
            };
            const Format = enum(c_int) {
                argb8888 = 0,
                xrgb8888 = 1,
                c8 = 0x20203843,
                rgb332 = 0x38424752,
                bgr233 = 0x38524742,
                xrgb4444 = 0x32315258,
                xbgr4444 = 0x32314258,
                rgbx4444 = 0x32315852,
                bgrx4444 = 0x32315842,
                argb4444 = 0x32315241,
                abgr4444 = 0x32314241,
                rgba4444 = 0x32314152,
                bgra4444 = 0x32314142,
                xrgb1555 = 0x35315258,
                xbgr1555 = 0x35314258,
                rgbx5551 = 0x35315852,
                bgrx5551 = 0x35315842,
                argb1555 = 0x35315241,
                abgr1555 = 0x35314241,
                rgba5551 = 0x35314152,
                bgra5551 = 0x35314142,
                rgb565 = 0x36314752,
                bgr565 = 0x36314742,
                rgb888 = 0x34324752,
                bgr888 = 0x34324742,
                xbgr8888 = 0x34324258,
                rgbx8888 = 0x34325852,
                bgrx8888 = 0x34325842,
                abgr8888 = 0x34324241,
                rgba8888 = 0x34324152,
                bgra8888 = 0x34324142,
                xrgb2101010 = 0x30335258,
                xbgr2101010 = 0x30334258,
                rgbx1010102 = 0x30335852,
                bgrx1010102 = 0x30335842,
                argb2101010 = 0x30335241,
                abgr2101010 = 0x30334241,
                rgba1010102 = 0x30334152,
                bgra1010102 = 0x30334142,
                yuyv = 0x56595559,
                yvyu = 0x55595659,
                uyvy = 0x59565955,
                vyuy = 0x59555956,
                ayuv = 0x56555941,
                nv12 = 0x3231564e,
                nv21 = 0x3132564e,
                nv16 = 0x3631564e,
                nv61 = 0x3136564e,
                yuv410 = 0x39565559,
                yvu410 = 0x39555659,
                yuv411 = 0x31315559,
                yvu411 = 0x31315659,
                yuv420 = 0x32315559,
                yvu420 = 0x32315659,
                yuv422 = 0x36315559,
                yvu422 = 0x36315659,
                yuv444 = 0x34325559,
                yvu444 = 0x34325659,
                r8 = 0x20203852,
                r16 = 0x20363152,
                rg88 = 0x38384752,
                gr88 = 0x38385247,
                rg1616 = 0x32334752,
                gr1616 = 0x32335247,
                xrgb16161616f = 0x48345258,
                xbgr16161616f = 0x48344258,
                argb16161616f = 0x48345241,
                abgr16161616f = 0x48344241,
                xyuv8888 = 0x56555958,
                vuy888 = 0x34325556,
                vuy101010 = 0x30335556,
                y210 = 0x30313259,
                y212 = 0x32313259,
                y216 = 0x36313259,
                y410 = 0x30313459,
                y412 = 0x32313459,
                y416 = 0x36313459,
                xvyu2101010 = 0x30335658,
                xvyu12_16161616 = 0x36335658,
                xvyu16161616 = 0x38345658,
                y0l0 = 0x304c3059,
                x0l0 = 0x304c3058,
                y0l2 = 0x324c3059,
                x0l2 = 0x324c3058,
                yuv420_8bit = 0x38305559,
                yuv420_10bit = 0x30315559,
                xrgb8888_a8 = 0x38415258,
                xbgr8888_a8 = 0x38414258,
                rgbx8888_a8 = 0x38415852,
                bgrx8888_a8 = 0x38415842,
                rgb888_a8 = 0x38413852,
                bgr888_a8 = 0x38413842,
                rgb565_a8 = 0x38413552,
                bgr565_a8 = 0x38413542,
                nv24 = 0x3432564e,
                nv42 = 0x3234564e,
                p210 = 0x30313250,
                p010 = 0x30313050,
                p012 = 0x32313050,
                p016 = 0x36313050,
                axbxgxrx106106106106 = 0x30314241,
                nv15 = 0x3531564e,
                q410 = 0x30313451,
                q401 = 0x31303451,
                xrgb16161616 = 0x38345258,
                xbgr16161616 = 0x38344258,
                argb16161616 = 0x38345241,
                abgr16161616 = 0x38344241,
                c1 = 0x20203143,
                c2 = 0x20203243,
                c4 = 0x20203443,
                d1 = 0x20203144,
                d2 = 0x20203244,
                d4 = 0x20203444,
                d8 = 0x20203844,
                r1 = 0x20203152,
                r2 = 0x20203252,
                r4 = 0x20203452,
                r10 = 0x20303152,
                r12 = 0x20323152,
                avuy8888 = 0x59555641,
                xvuy8888 = 0x59555658,
                p030 = 0x30333050,
                _,
            };
        };
        const shm_pool = struct {
            const interface: common.Interface = .{
                .name = "wl_shm_pool",
                .version = 2,
                .method_count = 3,
                .methods = &.{
                    .{
                        .name = "create_buffer",
                        .signature = "niiiiu",
                        .types = &.{
                            &common.wl.buffer.interface,
                            null,
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "resize",
                        .signature = "i",
                        .types = &.{
                            null,
                        },
                    },
                },
                .event_count = 0,
                .events = null,
            };
        };
        const data_device_manager = struct {
            const interface: common.Interface = .{
                .name = "wl_data_device_manager",
                .version = 3,
                .method_count = 2,
                .methods = &.{
                    .{
                        .name = "create_data_source",
                        .signature = "n",
                        .types = &.{
                            &common.wl.data_source.interface,
                        },
                    },
                    .{
                        .name = "get_data_device",
                        .signature = "no",
                        .types = &.{
                            &common.wl.data_device.interface,
                            &common.wl.seat.interface,
                        },
                    },
                },
                .event_count = 0,
                .events = null,
            };
        };
        const data_source = struct {
            const interface: common.Interface = .{
                .name = "wl_data_source",
                .version = 3,
                .method_count = 3,
                .methods = &.{
                    .{
                        .name = "offer",
                        .signature = "s",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "set_actions",
                        .signature = "3u",
                        .types = &.{
                            null,
                        },
                    },
                },
                .event_count = 6,
                .events = &.{
                    .{
                        .name = "target",
                        .signature = "?s",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "send",
                        .signature = "sh",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "cancelled",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "dnd_drop_performed",
                        .signature = "3",
                        .types = null,
                    },
                    .{
                        .name = "dnd_finished",
                        .signature = "3",
                        .types = null,
                    },
                    .{
                        .name = "action",
                        .signature = "3u",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
        };
        const data_device = struct {
            const interface: common.Interface = .{
                .name = "wl_data_device",
                .version = 3,
                .method_count = 3,
                .methods = &.{
                    .{
                        .name = "start_drag",
                        .signature = "?oo?ou",
                        .types = &.{
                            &common.wl.data_source.interface,
                            &common.wl.surface.interface,
                            &common.wl.surface.interface,
                            null,
                        },
                    },
                    .{
                        .name = "set_selection",
                        .signature = "?ou",
                        .types = &.{
                            &common.wl.data_source.interface,
                            null,
                        },
                    },
                    .{
                        .name = "release",
                        .signature = "2",
                        .types = null,
                    },
                },
                .event_count = 6,
                .events = &.{
                    .{
                        .name = "data_offer",
                        .signature = "n",
                        .types = &.{
                            &common.wl.data_offer.interface,
                        },
                    },
                    .{
                        .name = "enter",
                        .signature = "uoff?o",
                        .types = &.{
                            null,
                            &common.wl.surface.interface,
                            null,
                            null,
                            &common.wl.data_offer.interface,
                        },
                    },
                    .{
                        .name = "leave",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "motion",
                        .signature = "uff",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "drop",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "selection",
                        .signature = "?o",
                        .types = &.{
                            &common.wl.data_offer.interface,
                        },
                    },
                },
            };
        };
        const data_offer = struct {
            const interface: common.Interface = .{
                .name = "wl_data_offer",
                .version = 3,
                .method_count = 5,
                .methods = &.{
                    .{
                        .name = "accept",
                        .signature = "u?s",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "receive",
                        .signature = "sh",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "finish",
                        .signature = "3",
                        .types = null,
                    },
                    .{
                        .name = "set_actions",
                        .signature = "3uu",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                },
                .event_count = 3,
                .events = &.{
                    .{
                        .name = "offer",
                        .signature = "s",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "source_actions",
                        .signature = "3u",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "action",
                        .signature = "3u",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
        };
        const shell = struct {
            const interface: common.Interface = .{
                .name = "wl_shell",
                .version = 1,
                .method_count = 1,
                .methods = &.{
                    .{
                        .name = "get_shell_surface",
                        .signature = "no",
                        .types = &.{
                            &common.wl.shell_surface.interface,
                            &common.wl.surface.interface,
                        },
                    },
                },
                .event_count = 0,
                .events = null,
            };
        };
        const shell_surface = struct {
            const interface: common.Interface = .{
                .name = "wl_shell_surface",
                .version = 1,
                .method_count = 10,
                .methods = &.{
                    .{
                        .name = "pong",
                        .signature = "u",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "move",
                        .signature = "ou",
                        .types = &.{
                            &common.wl.seat.interface,
                            null,
                        },
                    },
                    .{
                        .name = "resize",
                        .signature = "ouu",
                        .types = &.{
                            &common.wl.seat.interface,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "set_toplevel",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "set_transient",
                        .signature = "oiiu",
                        .types = &.{
                            &common.wl.surface.interface,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "set_fullscreen",
                        .signature = "uu?o",
                        .types = &.{
                            null,
                            null,
                            &common.wl.output.interface,
                        },
                    },
                    .{
                        .name = "set_popup",
                        .signature = "ouoiiu",
                        .types = &.{
                            &common.wl.seat.interface,
                            null,
                            &common.wl.surface.interface,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "set_maximized",
                        .signature = "?o",
                        .types = &.{
                            &common.wl.output.interface,
                        },
                    },
                    .{
                        .name = "set_title",
                        .signature = "s",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "set_class",
                        .signature = "s",
                        .types = &.{
                            null,
                        },
                    },
                },
                .event_count = 3,
                .events = &.{
                    .{
                        .name = "ping",
                        .signature = "u",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "configure",
                        .signature = "uii",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "popup_done",
                        .signature = "",
                        .types = null,
                    },
                },
            };
        };
        const seat = struct {
            const interface: common.Interface = .{
                .name = "wl_seat",
                .version = 10,
                .method_count = 4,
                .methods = &.{
                    .{
                        .name = "get_pointer",
                        .signature = "n",
                        .types = &.{
                            &common.wl.pointer.interface,
                        },
                    },
                    .{
                        .name = "get_keyboard",
                        .signature = "n",
                        .types = &.{
                            &common.wl.keyboard.interface,
                        },
                    },
                    .{
                        .name = "get_touch",
                        .signature = "n",
                        .types = &.{
                            &common.wl.touch.interface,
                        },
                    },
                    .{
                        .name = "release",
                        .signature = "5",
                        .types = null,
                    },
                },
                .event_count = 2,
                .events = &.{
                    .{
                        .name = "capabilities",
                        .signature = "u",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "name",
                        .signature = "2s",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
            const Capability = packed struct(u32) {
                pointer: bool = false,
                keyboard: bool = false,
                touch: bool = false,
                _padding3: bool = false,
                _padding4: bool = false,
                _padding5: bool = false,
                _padding6: bool = false,
                _padding7: bool = false,
                _padding8: bool = false,
                _padding9: bool = false,
                _padding10: bool = false,
                _padding11: bool = false,
                _padding12: bool = false,
                _padding13: bool = false,
                _padding14: bool = false,
                _padding15: bool = false,
                _padding16: bool = false,
                _padding17: bool = false,
                _padding18: bool = false,
                _padding19: bool = false,
                _padding20: bool = false,
                _padding21: bool = false,
                _padding22: bool = false,
                _padding23: bool = false,
                _padding24: bool = false,
                _padding25: bool = false,
                _padding26: bool = false,
                _padding27: bool = false,
                _padding28: bool = false,
                _padding29: bool = false,
                _padding30: bool = false,
                _padding31: bool = false,
                pub const Enum = enum(c_int) {
                    pointer = 1,
                    keyboard = 2,
                    touch = 4,
                    _,
                };
            };
            const Error = enum(c_int) {
                missing_capability = 0,
                _,
            };
        };
        const pointer = struct {
            const interface: common.Interface = .{
                .name = "wl_pointer",
                .version = 10,
                .method_count = 2,
                .methods = &.{
                    .{
                        .name = "set_cursor",
                        .signature = "u?oii",
                        .types = &.{
                            null,
                            &common.wl.surface.interface,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "release",
                        .signature = "3",
                        .types = null,
                    },
                },
                .event_count = 11,
                .events = &.{
                    .{
                        .name = "enter",
                        .signature = "uoff",
                        .types = &.{
                            null,
                            &common.wl.surface.interface,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "leave",
                        .signature = "uo",
                        .types = &.{
                            null,
                            &common.wl.surface.interface,
                        },
                    },
                    .{
                        .name = "motion",
                        .signature = "uff",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "button",
                        .signature = "uuuu",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "axis",
                        .signature = "uuf",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "frame",
                        .signature = "5",
                        .types = null,
                    },
                    .{
                        .name = "axis_source",
                        .signature = "5u",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "axis_stop",
                        .signature = "5uu",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "axis_discrete",
                        .signature = "5ui",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "axis_value120",
                        .signature = "8ui",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "axis_relative_direction",
                        .signature = "9uu",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                },
            };
            const Error = enum(c_int) {
                role = 0,
                _,
            };
            const ButtonState = enum(c_int) {
                released = 0,
                pressed = 1,
                _,
            };
            const Axis = enum(c_int) {
                vertical_scroll = 0,
                horizontal_scroll = 1,
                _,
            };
            const AxisSource = enum(c_int) {
                wheel = 0,
                finger = 1,
                continuous = 2,
                _,
            };
            const AxisRelativeDirection = enum(c_int) {
                identical = 0,
                inverted = 1,
                _,
            };
        };
        const keyboard = struct {
            const interface: common.Interface = .{
                .name = "wl_keyboard",
                .version = 10,
                .method_count = 1,
                .methods = &.{
                    .{
                        .name = "release",
                        .signature = "3",
                        .types = null,
                    },
                },
                .event_count = 6,
                .events = &.{
                    .{
                        .name = "keymap",
                        .signature = "uhu",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "enter",
                        .signature = "uoa",
                        .types = &.{
                            null,
                            &common.wl.surface.interface,
                            null,
                        },
                    },
                    .{
                        .name = "leave",
                        .signature = "uo",
                        .types = &.{
                            null,
                            &common.wl.surface.interface,
                        },
                    },
                    .{
                        .name = "key",
                        .signature = "uuuu",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "modifiers",
                        .signature = "uuuuu",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "repeat_info",
                        .signature = "4ii",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                },
            };
            const KeymapFormat = enum(c_int) {
                no_keymap = 0,
                xkb_v1 = 1,
                _,
            };
            const KeyState = enum(c_int) {
                released = 0,
                pressed = 1,
                _,
            };
        };
        const touch = struct {
            const interface: common.Interface = .{
                .name = "wl_touch",
                .version = 10,
                .method_count = 1,
                .methods = &.{
                    .{
                        .name = "release",
                        .signature = "3",
                        .types = null,
                    },
                },
                .event_count = 7,
                .events = &.{
                    .{
                        .name = "down",
                        .signature = "uuoiff",
                        .types = &.{
                            null,
                            null,
                            &common.wl.surface.interface,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "up",
                        .signature = "uui",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "motion",
                        .signature = "uiff",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "frame",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "cancel",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "shape",
                        .signature = "6iff",
                        .types = &.{
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "orientation",
                        .signature = "6if",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                },
            };
        };
        const output = struct {
            const interface: common.Interface = .{
                .name = "wl_output",
                .version = 4,
                .method_count = 1,
                .methods = &.{
                    .{
                        .name = "release",
                        .signature = "3",
                        .types = null,
                    },
                },
                .event_count = 6,
                .events = &.{
                    .{
                        .name = "geometry",
                        .signature = "iiiiissi",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "mode",
                        .signature = "uiii",
                        .types = &.{
                            null,
                            null,
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "done",
                        .signature = "2",
                        .types = null,
                    },
                    .{
                        .name = "scale",
                        .signature = "2i",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "name",
                        .signature = "4s",
                        .types = &.{
                            null,
                        },
                    },
                    .{
                        .name = "description",
                        .signature = "4s",
                        .types = &.{
                            null,
                        },
                    },
                },
            };
            const Subpixel = enum(c_int) {
                unknown = 0,
                none = 1,
                horizontal_rgb = 2,
                horizontal_bgr = 3,
                vertical_rgb = 4,
                vertical_bgr = 5,
                _,
            };
            const Transform = enum(c_int) {
                normal = 0,
                @"90" = 1,
                @"180" = 2,
                @"270" = 3,
                flipped = 4,
                flipped_90 = 5,
                flipped_180 = 6,
                flipped_270 = 7,
                _,
            };
            const Mode = packed struct(u32) {
                current: bool = false,
                preferred: bool = false,
                _padding2: bool = false,
                _padding3: bool = false,
                _padding4: bool = false,
                _padding5: bool = false,
                _padding6: bool = false,
                _padding7: bool = false,
                _padding8: bool = false,
                _padding9: bool = false,
                _padding10: bool = false,
                _padding11: bool = false,
                _padding12: bool = false,
                _padding13: bool = false,
                _padding14: bool = false,
                _padding15: bool = false,
                _padding16: bool = false,
                _padding17: bool = false,
                _padding18: bool = false,
                _padding19: bool = false,
                _padding20: bool = false,
                _padding21: bool = false,
                _padding22: bool = false,
                _padding23: bool = false,
                _padding24: bool = false,
                _padding25: bool = false,
                _padding26: bool = false,
                _padding27: bool = false,
                _padding28: bool = false,
                _padding29: bool = false,
                _padding30: bool = false,
                _padding31: bool = false,
                pub const Enum = enum(c_int) {
                    current = 0x1,
                    preferred = 0x2,
                    _,
                };
            };
        };
        const subcompositor = struct {
            const interface: common.Interface = .{
                .name = "wl_subcompositor",
                .version = 1,
                .method_count = 2,
                .methods = &.{
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "get_subsurface",
                        .signature = "noo",
                        .types = &.{
                            &common.wl.subsurface.interface,
                            &common.wl.surface.interface,
                            &common.wl.surface.interface,
                        },
                    },
                },
                .event_count = 0,
                .events = null,
            };
        };
        const subsurface = struct {
            const interface: common.Interface = .{
                .name = "wl_subsurface",
                .version = 1,
                .method_count = 6,
                .methods = &.{
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "set_position",
                        .signature = "ii",
                        .types = &.{
                            null,
                            null,
                        },
                    },
                    .{
                        .name = "place_above",
                        .signature = "o",
                        .types = &.{
                            &common.wl.surface.interface,
                        },
                    },
                    .{
                        .name = "place_below",
                        .signature = "o",
                        .types = &.{
                            &common.wl.surface.interface,
                        },
                    },
                    .{
                        .name = "set_sync",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "set_desync",
                        .signature = "",
                        .types = null,
                    },
                },
                .event_count = 0,
                .events = null,
            };
        };
        const fixes = struct {
            const interface: common.Interface = .{
                .name = "wl_fixes",
                .version = 1,
                .method_count = 2,
                .methods = &.{
                    .{
                        .name = "destroy",
                        .signature = "",
                        .types = null,
                    },
                    .{
                        .name = "destroy_registry",
                        .signature = "o",
                        .types = &.{
                            &common.wl.registry.interface,
                        },
                    },
                },
                .event_count = 0,
                .events = null,
            };
        };
    };
};
