Skip to content

Instantly share code, notes, and snippets.

@tadeokondrak
Created April 28, 2020 13:14
Show Gist options
  • Save tadeokondrak/6c7f5b9457ce137af90feaf1d94684d9 to your computer and use it in GitHub Desktop.
Save tadeokondrak/6c7f5b9457ce137af90feaf1d94684d9 to your computer and use it in GitHub Desktop.
pub const wayland = @import("wayland.zig");
/// wl_display: core global object
///
/// The core global object. This is a special singleton object. It
/// is used for internal Wayland protocol features.
pub const Display = struct {
resource: wayland.server.Resource,
pub fn version(display: Display) u32 {
return display.resource.version();
}
pub fn data(display: Display, comptime T: type) ?*T {
return display.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
sync: Sync,
get_registry: GetRegistry,
/// sync: asynchronous roundtrip
///
/// The sync request asks the server to emit the 'done' event
/// on the returned wl_callback object. Since requests are
/// handled in-order and events are delivered in-order, this can
/// be used as a barrier to ensure all previous requests and the
/// resulting events have been handled.
/// The object returned by this request will be destroyed by the
/// compositor after the callback is fired and as such the client must not
/// attempt to use it after that point.
/// The callback_data passed in the callback is the event serial.
pub const Sync = struct {
callback: Callback,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// get_registry: get global registry object
///
/// This request creates a registry object that allows the client
/// to list and bind the global objects available from the
/// compositor.
/// It should be noted that the server side resources consumed in
/// response to a get_registry request can only be released when the
/// client disconnects, not when the client side proxy is destroyed.
/// Therefore, clients should invoke get_registry as infrequently as
/// possible to avoid wasting memory.
pub const GetRegistry = struct {
registry: Registry,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
};
pub const Event = union(enum) {
@"error": ErrorEvent,
delete_id: DeleteId,
/// error: fatal error event
///
/// The error event is sent out when a fatal (non-recoverable)
/// error has occurred. The object_id argument is the object
/// where the error occurred, most often in response to a request
/// to that object. The code identifies the error and is defined
/// by the object interface. As such, each interface defines its
/// own set of error codes. The message is a brief description
/// of the error, for (debugging) convenience.
pub const ErrorEvent = struct {
object_id: wayland.server.Resource,
code: u32,
message: []const u8,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// delete_id: acknowledge object ID deletion
///
/// This event is used internally by the object ID management
/// logic. When a client deletes an object that it had created,
/// the server will send this event to acknowledge that it has
/// seen the delete request. When the client receives this event,
/// it will know that it can safely reuse the object ID.
pub const DeleteId = struct {
id: u32,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
};
/// error: global error values
///
/// These errors are global and can be emitted in response to any
/// server request.
pub const Error = error{
InvalidObject,
InvalidMethod,
NoMemory,
Implementation,
};
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.InvalidObject,
1 => Error.InvalidMethod,
2 => Error.NoMemory,
3 => Error.Implementation,
else => null,
};
}
pub fn errorToInt(e: Error) u32 {
return switch (i) {
Error.InvalidObject => 0,
Error.InvalidMethod => 1,
Error.NoMemory => 2,
Error.Implementation => 3,
};
}
pub const error_invalid_object_since_version = 1;
pub const error_invalid_method_since_version = 1;
pub const error_no_memory_since_version = 1;
pub const error_implementation_since_version = 1;
pub fn marshal(display: Display, event: Event) void {
switch (event) {
.@"error" => |@"error"| {
if (!display.resource.client.wire.putUint(display.resource.id)) return;
if (!display.resource.client.wire.putUint(((@as(u32, 20 + @truncate(u32, @"error".message.len)) << 16) & 0xffff0000) | (Event.ErrorEvent.opcode & 0x0000ffff))) return;
if (!display.resource.client.wire.putUint(@"error".object_id.id)) return;
if (!display.resource.client.wire.putUint(@"error".code)) return;
if (!display.resource.client.wire.putString(@"error".message)) return;
},
.delete_id => |delete_id| {
if (!display.resource.client.wire.putUint(display.resource.id)) return;
if (!display.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.DeleteId.opcode & 0x0000ffff))) return;
if (!display.resource.client.wire.putUint(delete_id.id)) return;
},
}
}
pub fn unmarshal(display: Display, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Sync.opcode => {
var sync: Request.Sync = undefined;
return @as(Request, .{ .sync = sync });
},
Request.GetRegistry.opcode => {
var get_registry: Request.GetRegistry = undefined;
return @as(Request, .{ .get_registry = get_registry });
},
else => return null,
}
}
};
/// wl_registry: global registry object
///
/// The singleton global registry object. The server has a number of
/// global objects that are available to all clients. These objects
/// typically represent an actual object in the server (for example,
/// an input device) or they are singleton objects that provide
/// extension functionality.
/// When a client creates a registry object, the registry object
/// will emit a global event for each global currently in the
/// registry. Globals come and go as a result of device or
/// monitor hotplugs, reconfiguration or other events, and the
/// registry will send out global and global_remove events to
/// keep the client up to date with the changes. To mark the end
/// of the initial burst of events, the client can use the
/// wl_display.sync request immediately after calling
/// wl_display.get_registry.
/// A client can bind to a global object by using the bind
/// request. This creates a client-side handle that lets the object
/// emit events to the client and lets the client invoke requests on
/// the object.
pub const Registry = struct {
resource: wayland.server.Resource,
pub fn version(registry: Registry) u32 {
return registry.resource.version();
}
pub fn data(registry: Registry, comptime T: type) ?*T {
return registry.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
bind: Bind,
/// bind: bind an object to the display
///
/// Binds a new, client-created object to the server using the
/// specified name as the identifier.
pub const Bind = struct {
name: u32,
id: wayland.server.Resource,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
};
pub const Event = union(enum) {
global: Global,
global_remove: GlobalRemove,
/// global: announce global object
///
/// Notify the client of global objects.
/// The event notifies the client that a global object with
/// the given name is now available, and it implements the
/// given version of the given interface.
pub const Global = struct {
name: u32,
interface: []const u8,
version: u32,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// global_remove: announce removal of global object
///
/// Notify the client of removed global objects.
/// This event notifies the client that the global identified
/// by name is no longer available. If the client bound to
/// the global using the bind request, the client should now
/// destroy that object.
/// The object remains valid and requests to the object will be
/// ignored until the client destroys it, to avoid races between
/// the global going away and a client sending a request to it.
pub const GlobalRemove = struct {
name: u32,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
};
pub fn marshal(registry: Registry, event: Event) void {
switch (event) {
.global => |global| {
if (!registry.resource.client.wire.putUint(registry.resource.id)) return;
if (!registry.resource.client.wire.putUint(((@as(u32, 20 + @truncate(u32, global.interface.len)) << 16) & 0xffff0000) | (Event.Global.opcode & 0x0000ffff))) return;
if (!registry.resource.client.wire.putUint(global.name)) return;
if (!registry.resource.client.wire.putString(global.interface)) return;
if (!registry.resource.client.wire.putUint(global.version)) return;
},
.global_remove => |global_remove| {
if (!registry.resource.client.wire.putUint(registry.resource.id)) return;
if (!registry.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.GlobalRemove.opcode & 0x0000ffff))) return;
if (!registry.resource.client.wire.putUint(global_remove.name)) return;
},
}
}
pub fn unmarshal(registry: Registry, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Bind.opcode => {
var bind: Request.Bind = undefined;
if (p.len < 4) return null;
bind.name = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
return @as(Request, .{ .bind = bind });
},
else => return null,
}
}
};
/// wl_callback: callback object
///
/// Clients can handle the 'done' event to get notified when
/// the related request is done.
pub const Callback = struct {
resource: wayland.server.Resource,
pub fn version(callback: Callback) u32 {
return callback.resource.version();
}
pub fn data(callback: Callback, comptime T: type) ?*T {
return callback.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {};
pub const Event = union(enum) {
done: Done,
/// done: done event
///
/// Notify the client when the related request is done.
pub const Done = struct {
callback_data: u32,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
};
pub fn marshal(callback: Callback, event: Event) void {
switch (event) {
.done => |done| {
if (!callback.resource.client.wire.putUint(callback.resource.id)) return;
if (!callback.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Done.opcode & 0x0000ffff))) return;
if (!callback.resource.client.wire.putUint(done.callback_data)) return;
},
}
}
pub fn unmarshal(callback: Callback, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
else => return null,
}
}
};
/// wl_compositor: the compositor singleton
///
/// A compositor. This object is a singleton global. The
/// compositor is in charge of combining the contents of multiple
/// surfaces into one displayable output.
pub const Compositor = struct {
resource: wayland.server.Resource,
pub fn version(compositor: Compositor) u32 {
return compositor.resource.version();
}
pub fn data(compositor: Compositor, comptime T: type) ?*T {
return compositor.resource.data(T);
}
pub const interface_version = 4;
pub const Request = union(enum) {
create_surface: CreateSurface,
create_region: CreateRegion,
/// create_surface: create new surface
///
/// Ask the compositor to create a new surface.
pub const CreateSurface = struct {
id: Surface,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// create_region: create new region
///
/// Ask the compositor to create a new region.
pub const CreateRegion = struct {
id: Region,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
};
pub const Event = union(enum) {};
pub fn marshal(compositor: Compositor, event: Event) void {
switch (event) {}
}
pub fn unmarshal(compositor: Compositor, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.CreateSurface.opcode => {
var create_surface: Request.CreateSurface = undefined;
return @as(Request, .{ .create_surface = create_surface });
},
Request.CreateRegion.opcode => {
var create_region: Request.CreateRegion = undefined;
return @as(Request, .{ .create_region = create_region });
},
else => return null,
}
}
};
/// wl_shm_pool: a shared memory pool
///
/// The wl_shm_pool object encapsulates a piece of memory shared
/// between the compositor and client. Through the wl_shm_pool
/// object, the client can allocate shared memory wl_buffer objects.
/// All objects created through the same pool share the same
/// underlying mapped memory. Reusing the mapped memory avoids the
/// setup/teardown overhead and is useful when interactively resizing
/// a surface or for many small buffers.
pub const ShmPool = struct {
resource: wayland.server.Resource,
pub fn version(shm_pool: ShmPool) u32 {
return shm_pool.resource.version();
}
pub fn data(shm_pool: ShmPool, comptime T: type) ?*T {
return shm_pool.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
create_buffer: CreateBuffer,
destroy: Destroy,
resize: Resize,
/// create_buffer: create a buffer from the pool
///
/// Create a wl_buffer object from the pool.
/// The buffer is created offset bytes into the pool and has
/// width and height as specified. The stride argument specifies
/// the number of bytes from the beginning of one row to the beginning
/// of the next. The format is the pixel format of the buffer and
/// must be one of those advertised through the wl_shm.format event.
/// A buffer will keep a reference to the pool it was created from
/// so it is valid to destroy the pool immediately after creating
/// a buffer from it.
pub const CreateBuffer = struct {
id: Buffer,
offset: i32,
width: i32,
height: i32,
stride: i32,
format: ShmFormat,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// destroy: destroy the pool
///
/// Destroy the shared memory pool.
/// The mmapped memory will be released when all
/// buffers that have been created from this pool
/// are gone.
pub const Destroy = struct {
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = true;
};
/// resize: change the size of the pool mapping
///
/// This request will cause the server to remap the backing memory
/// for the pool from the file descriptor passed when the pool was
/// created, but using the new size. This request can only be
/// used to make the pool bigger.
pub const Resize = struct {
size: i32,
pub const since_version = 1;
pub const opcode: u16 = 2;
pub const destructor = false;
};
};
pub const Event = union(enum) {};
pub fn marshal(shm_pool: ShmPool, event: Event) void {
switch (event) {}
}
pub fn unmarshal(shm_pool: ShmPool, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.CreateBuffer.opcode => {
var create_buffer: Request.CreateBuffer = undefined;
if (p.len < 4) return null;
create_buffer.offset = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
create_buffer.width = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
create_buffer.height = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
create_buffer.stride = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
create_buffer.format = @import("std").mem.bytesAsSlice(ShmFormat, p)[0];
p = p[@sizeOf(ShmFormat)..];
return @as(Request, .{ .create_buffer = create_buffer });
},
Request.Destroy.opcode => {
var destroy: Request.Destroy = undefined;
return @as(Request, .{ .destroy = destroy });
},
Request.Resize.opcode => {
var resize: Request.Resize = undefined;
if (p.len < 4) return null;
resize.size = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .resize = resize });
},
else => return null,
}
}
};
/// wl_shm: shared memory support
///
/// A singleton global object that provides support for shared
/// memory.
/// Clients can create wl_shm_pool objects using the create_pool
/// request.
/// At connection setup time, the wl_shm object emits one or more
/// format events to inform clients about the valid pixel formats
/// that can be used for buffers.
pub const Shm = struct {
resource: wayland.server.Resource,
pub fn version(shm: Shm) u32 {
return shm.resource.version();
}
pub fn data(shm: Shm, comptime T: type) ?*T {
return shm.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
create_pool: CreatePool,
/// create_pool: create a shm pool
///
/// Create a new wl_shm_pool object.
/// The pool can be used to create shared memory based buffer
/// objects. The server will mmap size bytes of the passed file
/// descriptor, to use as backing memory for the pool.
pub const CreatePool = struct {
id: ShmPool,
fd: c_int,
size: i32,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
};
pub const Event = union(enum) {
format: Format,
/// format: pixel format description
///
/// Informs the client about a valid pixel format that
/// can be used for buffers. Known formats include
/// argb8888 and xrgb8888.
pub const Format = struct {
format: Format,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
};
/// error: wl_shm error values
///
/// These errors can be emitted in response to wl_shm requests.
pub const Error = error{
InvalidFormat,
InvalidStride,
InvalidFd,
} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.InvalidFormat,
1 => Error.InvalidStride,
2 => Error.InvalidFd,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.InvalidFormat => 0,
Error.InvalidStride => 1,
Error.InvalidFd => 2,
else => null,
};
}
pub const error_invalid_format_since_version = 1;
pub const error_invalid_stride_since_version = 1;
pub const error_invalid_fd_since_version = 1;
/// format: pixel formats
///
/// This describes the memory layout of an individual pixel.
/// All renderers should support argb8888 and xrgb8888 but any other
/// formats are optional and may not be supported by the particular
/// renderer in use.
/// The drm format codes match the macros defined in drm_fourcc.h, except
/// argb8888 and xrgb8888. The formats actually supported by the compositor
/// will be reported by the format event.
pub const Format = enum(u32) {
argb_8888 = 0,
xrgb_8888 = 1,
c_8 = 0x20203843,
rgb_332 = 0x38424752,
bgr_233 = 0x38524742,
xrgb_4444 = 0x32315258,
xbgr_4444 = 0x32314258,
rgbx_4444 = 0x32315852,
bgrx_4444 = 0x32315842,
argb_4444 = 0x32315241,
abgr_4444 = 0x32314241,
rgba_4444 = 0x32314152,
bgra_4444 = 0x32314142,
xrgb_1555 = 0x35315258,
xbgr_1555 = 0x35314258,
rgbx_5551 = 0x35315852,
bgrx_5551 = 0x35315842,
argb_1555 = 0x35315241,
abgr_1555 = 0x35314241,
rgba_5551 = 0x35314152,
bgra_5551 = 0x35314142,
rgb_565 = 0x36314752,
bgr_565 = 0x36314742,
rgb_888 = 0x34324752,
bgr_888 = 0x34324742,
xbgr_8888 = 0x34324258,
rgbx_8888 = 0x34325852,
bgrx_8888 = 0x34325842,
abgr_8888 = 0x34324241,
rgba_8888 = 0x34324152,
bgra_8888 = 0x34324142,
xrgb_2101010 = 0x30335258,
xbgr_2101010 = 0x30334258,
rgbx_1010102 = 0x30335852,
bgrx_1010102 = 0x30335842,
argb_2101010 = 0x30335241,
abgr_2101010 = 0x30334241,
rgba_1010102 = 0x30334152,
bgra_1010102 = 0x30334142,
yuyv = 0x56595559,
yvyu = 0x55595659,
uyvy = 0x59565955,
vyuy = 0x59555956,
ayuv = 0x56555941,
nv_12 = 0x3231564e,
nv_21 = 0x3132564e,
nv_16 = 0x3631564e,
nv_61 = 0x3136564e,
yuv_410 = 0x39565559,
yvu_410 = 0x39555659,
yuv_411 = 0x31315559,
yvu_411 = 0x31315659,
yuv_420 = 0x32315559,
yvu_420 = 0x32315659,
yuv_422 = 0x36315559,
yvu_422 = 0x36315659,
yuv_444 = 0x34325559,
yvu_444 = 0x34325659,
r_8 = 0x20203852,
r_16 = 0x20363152,
rg_88 = 0x38384752,
gr_88 = 0x38385247,
rg_1616 = 0x32334752,
gr_1616 = 0x32335247,
xrgb_16161616_f = 0x48345258,
xbgr_16161616_f = 0x48344258,
argb_16161616_f = 0x48345241,
abgr_16161616_f = 0x48344241,
xyuv_8888 = 0x56555958,
vuy_888 = 0x34325556,
vuy_101010 = 0x30335556,
y_210 = 0x30313259,
y_212 = 0x32313259,
y_216 = 0x36313259,
y_410 = 0x30313459,
y_412 = 0x32313459,
y_416 = 0x36313459,
xvyu_2101010 = 0x30335658,
xvyu_12__16161616 = 0x36335658,
xvyu_16161616 = 0x38345658,
y_0_l0 = 0x304c3059,
x_0_l0 = 0x304c3058,
y_0_l2 = 0x324c3059,
x_0_l2 = 0x324c3058,
yuv_420__8bit = 0x38305559,
yuv_420__10bit = 0x30315559,
xrgb_8888__a_8 = 0x38415258,
xbgr_8888__a_8 = 0x38414258,
rgbx_8888__a_8 = 0x38415852,
bgrx_8888__a_8 = 0x38415842,
rgb_888__a_8 = 0x38413852,
bgr_888__a_8 = 0x38413842,
rgb_565__a_8 = 0x38413552,
bgr_565__a_8 = 0x38413542,
nv_24 = 0x3432564e,
nv_42 = 0x3234564e,
p_210 = 0x30313250,
p_010 = 0x30313050,
p_012 = 0x32313050,
p_016 = 0x36313050,
pub const argb_8888_since_version = 1;
pub const xrgb_8888_since_version = 1;
pub const c_8_since_version = 1;
pub const rgb_332_since_version = 1;
pub const bgr_233_since_version = 1;
pub const xrgb_4444_since_version = 1;
pub const xbgr_4444_since_version = 1;
pub const rgbx_4444_since_version = 1;
pub const bgrx_4444_since_version = 1;
pub const argb_4444_since_version = 1;
pub const abgr_4444_since_version = 1;
pub const rgba_4444_since_version = 1;
pub const bgra_4444_since_version = 1;
pub const xrgb_1555_since_version = 1;
pub const xbgr_1555_since_version = 1;
pub const rgbx_5551_since_version = 1;
pub const bgrx_5551_since_version = 1;
pub const argb_1555_since_version = 1;
pub const abgr_1555_since_version = 1;
pub const rgba_5551_since_version = 1;
pub const bgra_5551_since_version = 1;
pub const rgb_565_since_version = 1;
pub const bgr_565_since_version = 1;
pub const rgb_888_since_version = 1;
pub const bgr_888_since_version = 1;
pub const xbgr_8888_since_version = 1;
pub const rgbx_8888_since_version = 1;
pub const bgrx_8888_since_version = 1;
pub const abgr_8888_since_version = 1;
pub const rgba_8888_since_version = 1;
pub const bgra_8888_since_version = 1;
pub const xrgb_2101010_since_version = 1;
pub const xbgr_2101010_since_version = 1;
pub const rgbx_1010102_since_version = 1;
pub const bgrx_1010102_since_version = 1;
pub const argb_2101010_since_version = 1;
pub const abgr_2101010_since_version = 1;
pub const rgba_1010102_since_version = 1;
pub const bgra_1010102_since_version = 1;
pub const yuyv_since_version = 1;
pub const yvyu_since_version = 1;
pub const uyvy_since_version = 1;
pub const vyuy_since_version = 1;
pub const ayuv_since_version = 1;
pub const nv_12_since_version = 1;
pub const nv_21_since_version = 1;
pub const nv_16_since_version = 1;
pub const nv_61_since_version = 1;
pub const yuv_410_since_version = 1;
pub const yvu_410_since_version = 1;
pub const yuv_411_since_version = 1;
pub const yvu_411_since_version = 1;
pub const yuv_420_since_version = 1;
pub const yvu_420_since_version = 1;
pub const yuv_422_since_version = 1;
pub const yvu_422_since_version = 1;
pub const yuv_444_since_version = 1;
pub const yvu_444_since_version = 1;
pub const r_8_since_version = 1;
pub const r_16_since_version = 1;
pub const rg_88_since_version = 1;
pub const gr_88_since_version = 1;
pub const rg_1616_since_version = 1;
pub const gr_1616_since_version = 1;
pub const xrgb_16161616_f_since_version = 1;
pub const xbgr_16161616_f_since_version = 1;
pub const argb_16161616_f_since_version = 1;
pub const abgr_16161616_f_since_version = 1;
pub const xyuv_8888_since_version = 1;
pub const vuy_888_since_version = 1;
pub const vuy_101010_since_version = 1;
pub const y_210_since_version = 1;
pub const y_212_since_version = 1;
pub const y_216_since_version = 1;
pub const y_410_since_version = 1;
pub const y_412_since_version = 1;
pub const y_416_since_version = 1;
pub const xvyu_2101010_since_version = 1;
pub const xvyu_12__16161616_since_version = 1;
pub const xvyu_16161616_since_version = 1;
pub const y_0_l0_since_version = 1;
pub const x_0_l0_since_version = 1;
pub const y_0_l2_since_version = 1;
pub const x_0_l2_since_version = 1;
pub const yuv_420__8bit_since_version = 1;
pub const yuv_420__10bit_since_version = 1;
pub const xrgb_8888__a_8_since_version = 1;
pub const xbgr_8888__a_8_since_version = 1;
pub const rgbx_8888__a_8_since_version = 1;
pub const bgrx_8888__a_8_since_version = 1;
pub const rgb_888__a_8_since_version = 1;
pub const bgr_888__a_8_since_version = 1;
pub const rgb_565__a_8_since_version = 1;
pub const bgr_565__a_8_since_version = 1;
pub const nv_24_since_version = 1;
pub const nv_42_since_version = 1;
pub const p_210_since_version = 1;
pub const p_010_since_version = 1;
pub const p_012_since_version = 1;
pub const p_016_since_version = 1;
pub fn fromInt(i: u32) Format {
return @intToEnum(Format, i);
}
pub fn toInt(e: Format) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
pub fn marshal(shm: Shm, event: Event) void {
switch (event) {
.format => |format| {
if (!shm.resource.client.wire.putUint(shm.resource.id)) return;
if (!shm.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Format.opcode & 0x0000ffff))) return;
if (!shm.resource.client.wire.putUint(format.format)) return;
},
}
}
pub fn unmarshal(shm: Shm, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.CreatePool.opcode => {
var create_pool: Request.CreatePool = undefined;
if (p.len < 4) return null;
create_pool.fd = @import("std").mem.bytesAsSlice(c_int, p)[0];
p = p[@sizeOf(c_int)..];
if (p.len < 4) return null;
create_pool.size = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .create_pool = create_pool });
},
else => return null,
}
}
};
/// wl_buffer: content for a wl_surface
///
/// A buffer provides the content for a wl_surface. Buffers are
/// created through factory interfaces such as wl_drm, wl_shm or
/// similar. It has a width and a height and can be attached to a
/// wl_surface, but the mechanism by which a client provides and
/// updates the contents is defined by the buffer factory interface.
pub const Buffer = struct {
resource: wayland.server.Resource,
pub fn version(buffer: Buffer) u32 {
return buffer.resource.version();
}
pub fn data(buffer: Buffer, comptime T: type) ?*T {
return buffer.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
destroy: Destroy,
/// destroy: destroy a buffer
///
/// Destroy a buffer. If and how you need to release the backing
/// storage is defined by the buffer factory interface.
/// For possible side-effects to a surface, see wl_surface.attach.
pub const Destroy = struct {
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = true;
};
};
pub const Event = union(enum) {
release: Release,
/// release: compositor releases buffer
///
/// Sent when this wl_buffer is no longer used by the compositor.
/// The client is now free to reuse or destroy this buffer and its
/// backing storage.
/// If a client receives a release event before the frame callback
/// requested in the same wl_surface.commit that attaches this
/// wl_buffer to a surface, then the client is immediately free to
/// reuse the buffer and its backing storage, and does not need a
/// second buffer for the next surface content update. Typically
/// this is possible, when the compositor maintains a copy of the
/// wl_surface contents, e.g. as a GL texture. This is an important
/// optimization for GL(ES) compositors with wl_shm clients.
pub const Release = struct {
pub const since_version = 1;
pub const opcode: u16 = 0;
};
};
pub fn marshal(buffer: Buffer, event: Event) void {
switch (event) {
.release => |release| {
if (!buffer.resource.client.wire.putUint(buffer.resource.id)) return;
if (!buffer.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.Release.opcode & 0x0000ffff))) return;
},
}
}
pub fn unmarshal(buffer: Buffer, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Destroy.opcode => {
var destroy: Request.Destroy = undefined;
return @as(Request, .{ .destroy = destroy });
},
else => return null,
}
}
};
/// wl_data_offer: offer to transfer data
///
/// A wl_data_offer represents a piece of data offered for transfer
/// by another client (the source client). It is used by the
/// copy-and-paste and drag-and-drop mechanisms. The offer
/// describes the different mime types that the data can be
/// converted to and provides the mechanism for transferring the
/// data directly from the source client.
pub const DataOffer = struct {
resource: wayland.server.Resource,
pub fn version(data_offer: DataOffer) u32 {
return data_offer.resource.version();
}
pub fn data(data_offer: DataOffer, comptime T: type) ?*T {
return data_offer.resource.data(T);
}
pub const interface_version = 3;
pub const Request = union(enum) {
accept: Accept,
receive: Receive,
destroy: Destroy,
finish: Finish,
set_actions: SetActions,
/// accept: accept one of the offered mime types
///
/// Indicate that the client can accept the given mime type, or
/// NULL for not accepted.
/// For objects of version 2 or older, this request is used by the
/// client to give feedback whether the client can receive the given
/// mime type, or NULL if none is accepted; the feedback does not
/// determine whether the drag-and-drop operation succeeds or not.
/// For objects of version 3 or newer, this request determines the
/// final result of the drag-and-drop operation. If the end result
/// is that no mime types were accepted, the drag-and-drop operation
/// will be cancelled and the corresponding drag source will receive
/// wl_data_source.cancelled. Clients may still use this event in
/// conjunction with wl_data_source.action for feedback.
pub const Accept = struct {
serial: u32,
mime_type: ?[]const u8,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// receive: request that the data is transferred
///
/// To transfer the offered data, the client issues this request
/// and indicates the mime type it wants to receive. The transfer
/// happens through the passed file descriptor (typically created
/// with the pipe system call). The source client writes the data
/// in the mime type representation requested and then closes the
/// file descriptor.
/// The receiving client reads from the read end of the pipe until
/// EOF and then closes its end, at which point the transfer is
/// complete.
/// This request may happen multiple times for different mime types,
/// both before and after wl_data_device.drop. Drag-and-drop destination
/// clients may preemptively fetch data or examine it more closely to
/// determine acceptance.
pub const Receive = struct {
mime_type: []const u8,
fd: c_int,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
/// destroy: destroy data offer
///
/// Destroy the data offer.
pub const Destroy = struct {
pub const since_version = 1;
pub const opcode: u16 = 2;
pub const destructor = true;
};
/// finish: the offer will no longer be used
///
/// Notifies the compositor that the drag destination successfully
/// finished the drag-and-drop operation.
/// Upon receiving this request, the compositor will emit
/// wl_data_source.dnd_finished on the drag source client.
/// It is a client error to perform other requests than
/// wl_data_offer.destroy after this one. It is also an error to perform
/// this request after a NULL mime type has been set in
/// wl_data_offer.accept or no action was received through
/// wl_data_offer.action.
/// If wl_data_offer.finish request is received for a non drag and drop
/// operation, the invalid_finish protocol error is raised.
pub const Finish = struct {
pub const since_version = 3;
pub const opcode: u16 = 3;
pub const destructor = false;
};
/// set_actions: set the available/preferred drag-and-drop actions
///
/// Sets the actions that the destination side client supports for
/// this operation. This request may trigger the emission of
/// wl_data_source.action and wl_data_offer.action events if the compositor
/// needs to change the selected action.
/// This request can be called multiple times throughout the
/// drag-and-drop operation, typically in response to wl_data_device.enter
/// or wl_data_device.motion events.
/// This request determines the final result of the drag-and-drop
/// operation. If the end result is that no action is accepted,
/// the drag source will receive wl_data_source.cancelled.
/// The dnd_actions argument must contain only values expressed in the
/// wl_data_device_manager.dnd_actions enum, and the preferred_action
/// argument must only contain one of those values set, otherwise it
/// will result in a protocol error.
/// While managing an "ask" action, the destination drag-and-drop client
/// may perform further wl_data_offer.receive requests, and is expected
/// to perform one last wl_data_offer.set_actions request with a preferred
/// action other than "ask" (and optionally wl_data_offer.accept) before
/// requesting wl_data_offer.finish, in order to convey the action selected
/// by the user. If the preferred action is not in the
/// wl_data_offer.source_actions mask, an error will be raised.
/// If the "ask" action is dismissed (e.g. user cancellation), the client
/// is expected to perform wl_data_offer.destroy right away.
/// This request can only be made on drag-and-drop offers, a protocol error
/// will be raised otherwise.
pub const SetActions = struct {
dnd_actions: DataDeviceManagerDndAction,
preferred_action: DataDeviceManagerDndAction,
pub const since_version = 3;
pub const opcode: u16 = 4;
pub const destructor = false;
};
};
pub const Event = union(enum) {
offer: Offer,
source_actions: SourceActions,
action: Action,
/// offer: advertise offered mime type
///
/// Sent immediately after creating the wl_data_offer object. One
/// event per offered mime type.
pub const Offer = struct {
mime_type: []const u8,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// source_actions: notify the source-side available actions
///
/// This event indicates the actions offered by the data source. It
/// will be sent right after wl_data_device.enter, or anytime the source
/// side changes its offered actions through wl_data_source.set_actions.
pub const SourceActions = struct {
source_actions: DataDeviceManagerDndAction,
pub const since_version = 3;
pub const opcode: u16 = 1;
};
/// action: notify the selected action
///
/// This event indicates the action selected by the compositor after
/// matching the source/destination side actions. Only one action (or
/// none) will be offered here.
/// This event can be emitted multiple times during the drag-and-drop
/// operation in response to destination side action changes through
/// wl_data_offer.set_actions.
/// This event will no longer be emitted after wl_data_device.drop
/// happened on the drag-and-drop destination, the client must
/// honor the last action received, or the last preferred one set
/// through wl_data_offer.set_actions when handling an "ask" action.
/// Compositors may also change the selected action on the fly, mainly
/// in response to keyboard modifier changes during the drag-and-drop
/// operation.
/// The most recent action received is always the valid one. Prior to
/// receiving wl_data_device.drop, the chosen action may change (e.g.
/// due to keyboard modifiers being pressed). At the time of receiving
/// wl_data_device.drop the drag-and-drop destination must honor the
/// last action received.
/// Action changes may still happen after wl_data_device.drop,
/// especially on "ask" actions, where the drag-and-drop destination
/// may choose another action afterwards. Action changes happening
/// at this stage are always the result of inter-client negotiation, the
/// compositor shall no longer be able to induce a different action.
/// Upon "ask" actions, it is expected that the drag-and-drop destination
/// may potentially choose a different action and/or mime type,
/// based on wl_data_offer.source_actions and finally chosen by the
/// user (e.g. popping up a menu with the available options). The
/// final wl_data_offer.set_actions and wl_data_offer.accept requests
/// must happen before the call to wl_data_offer.finish.
pub const Action = struct {
dnd_action: DataDeviceManagerDndAction,
pub const since_version = 3;
pub const opcode: u16 = 2;
};
};
/// error
pub const Error = error{
InvalidFinish,
InvalidActionMask,
InvalidAction,
InvalidOffer,
} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.InvalidFinish,
1 => Error.InvalidActionMask,
2 => Error.InvalidAction,
3 => Error.InvalidOffer,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.InvalidFinish => 0,
Error.InvalidActionMask => 1,
Error.InvalidAction => 2,
Error.InvalidOffer => 3,
else => null,
};
}
pub const error_invalid_finish_since_version = 1;
pub const error_invalid_action_mask_since_version = 1;
pub const error_invalid_action_since_version = 1;
pub const error_invalid_offer_since_version = 1;
pub fn marshal(data_offer: DataOffer, event: Event) void {
switch (event) {
.offer => |offer| {
if (!data_offer.resource.client.wire.putUint(data_offer.resource.id)) return;
if (!data_offer.resource.client.wire.putUint(((@as(u32, 12 + @truncate(u32, offer.mime_type.len)) << 16) & 0xffff0000) | (Event.Offer.opcode & 0x0000ffff))) return;
if (!data_offer.resource.client.wire.putString(offer.mime_type)) return;
},
.source_actions => |source_actions| {
if (!data_offer.resource.client.wire.putUint(data_offer.resource.id)) return;
if (!data_offer.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.SourceActions.opcode & 0x0000ffff))) return;
if (!data_offer.resource.client.wire.putUint(source_actions.source_actions)) return;
},
.action => |action| {
if (!data_offer.resource.client.wire.putUint(data_offer.resource.id)) return;
if (!data_offer.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Action.opcode & 0x0000ffff))) return;
if (!data_offer.resource.client.wire.putUint(action.dnd_action)) return;
},
}
}
pub fn unmarshal(data_offer: DataOffer, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Accept.opcode => {
var accept: Request.Accept = undefined;
if (p.len < 4) return null;
accept.serial = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
if (p.len < 4) return null;
accept.mime_type = @import("std").mem.bytesAsSlice(?[]const u8, p)[0];
p = p[@sizeOf(?[]const u8)..];
return @as(Request, .{ .accept = accept });
},
Request.Receive.opcode => {
var receive: Request.Receive = undefined;
if (p.len < 4) return null;
receive.mime_type = @import("std").mem.bytesAsSlice([]const u8, p)[0];
p = p[@sizeOf([]const u8)..];
if (p.len < 4) return null;
receive.fd = @import("std").mem.bytesAsSlice(c_int, p)[0];
p = p[@sizeOf(c_int)..];
return @as(Request, .{ .receive = receive });
},
Request.Destroy.opcode => {
var destroy: Request.Destroy = undefined;
return @as(Request, .{ .destroy = destroy });
},
Request.Finish.opcode => {
var finish: Request.Finish = undefined;
return @as(Request, .{ .finish = finish });
},
Request.SetActions.opcode => {
var set_actions: Request.SetActions = undefined;
if (p.len < 4) return null;
set_actions.dnd_actions = @import("std").mem.bytesAsSlice(DataDeviceManagerDndAction, p)[0];
p = p[@sizeOf(DataDeviceManagerDndAction)..];
if (p.len < 4) return null;
set_actions.preferred_action = @import("std").mem.bytesAsSlice(DataDeviceManagerDndAction, p)[0];
p = p[@sizeOf(DataDeviceManagerDndAction)..];
return @as(Request, .{ .set_actions = set_actions });
},
else => return null,
}
}
};
/// wl_data_source: offer to transfer data
///
/// The wl_data_source object is the source side of a wl_data_offer.
/// It is created by the source client in a data transfer and
/// provides a way to describe the offered data and a way to respond
/// to requests to transfer the data.
pub const DataSource = struct {
resource: wayland.server.Resource,
pub fn version(data_source: DataSource) u32 {
return data_source.resource.version();
}
pub fn data(data_source: DataSource, comptime T: type) ?*T {
return data_source.resource.data(T);
}
pub const interface_version = 3;
pub const Request = union(enum) {
offer: Offer,
destroy: Destroy,
set_actions: SetActions,
/// offer: add an offered mime type
///
/// This request adds a mime type to the set of mime types
/// advertised to targets. Can be called several times to offer
/// multiple types.
pub const Offer = struct {
mime_type: []const u8,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// destroy: destroy the data source
///
/// Destroy the data source.
pub const Destroy = struct {
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = true;
};
/// set_actions: set the available drag-and-drop actions
///
/// Sets the actions that the source side client supports for this
/// operation. This request may trigger wl_data_source.action and
/// wl_data_offer.action events if the compositor needs to change the
/// selected action.
/// The dnd_actions argument must contain only values expressed in the
/// wl_data_device_manager.dnd_actions enum, otherwise it will result
/// in a protocol error.
/// This request must be made once only, and can only be made on sources
/// used in drag-and-drop, so it must be performed before
/// wl_data_device.start_drag. Attempting to use the source other than
/// for drag-and-drop will raise a protocol error.
pub const SetActions = struct {
dnd_actions: DataDeviceManagerDndAction,
pub const since_version = 3;
pub const opcode: u16 = 2;
pub const destructor = false;
};
};
pub const Event = union(enum) {
target: Target,
send: Send,
cancelled: Cancelled,
dnd_drop_performed: DndDropPerformed,
dnd_finished: DndFinished,
action: Action,
/// target: a target accepts an offered mime type
///
/// Sent when a target accepts pointer_focus or motion events. If
/// a target does not accept any of the offered types, type is NULL.
/// Used for feedback during drag-and-drop.
pub const Target = struct {
mime_type: ?[]const u8,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// send: send the data
///
/// Request for data from the client. Send the data as the
/// specified mime type over the passed file descriptor, then
/// close it.
pub const Send = struct {
mime_type: []const u8,
fd: c_int,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
/// cancelled: selection was cancelled
///
/// This data source is no longer valid. There are several reasons why
/// this could happen:
/// - The data source has been replaced by another data source.
/// - The drag-and-drop operation was performed, but the drop destination
/// did not accept any of the mime types offered through
/// wl_data_source.target.
/// - The drag-and-drop operation was performed, but the drop destination
/// did not select any of the actions present in the mask offered through
/// wl_data_source.action.
/// - The drag-and-drop operation was performed but didn't happen over a
/// surface.
/// - The compositor cancelled the drag-and-drop operation (e.g. compositor
/// dependent timeouts to avoid stale drag-and-drop transfers).
/// The client should clean up and destroy this data source.
/// For objects of version 2 or older, wl_data_source.cancelled will
/// only be emitted if the data source was replaced by another data
/// source.
pub const Cancelled = struct {
pub const since_version = 1;
pub const opcode: u16 = 2;
};
/// dnd_drop_performed: the drag-and-drop operation physically finished
///
/// The user performed the drop action. This event does not indicate
/// acceptance, wl_data_source.cancelled may still be emitted afterwards
/// if the drop destination does not accept any mime type.
/// However, this event might however not be received if the compositor
/// cancelled the drag-and-drop operation before this event could happen.
/// Note that the data_source may still be used in the future and should
/// not be destroyed here.
pub const DndDropPerformed = struct {
pub const since_version = 3;
pub const opcode: u16 = 3;
};
/// dnd_finished: the drag-and-drop operation concluded
///
/// The drop destination finished interoperating with this data
/// source, so the client is now free to destroy this data source and
/// free all associated data.
/// If the action used to perform the operation was "move", the
/// source can now delete the transferred data.
pub const DndFinished = struct {
pub const since_version = 3;
pub const opcode: u16 = 4;
};
/// action: notify the selected action
///
/// This event indicates the action selected by the compositor after
/// matching the source/destination side actions. Only one action (or
/// none) will be offered here.
/// This event can be emitted multiple times during the drag-and-drop
/// operation, mainly in response to destination side changes through
/// wl_data_offer.set_actions, and as the data device enters/leaves
/// surfaces.
/// It is only possible to receive this event after
/// wl_data_source.dnd_drop_performed if the drag-and-drop operation
/// ended in an "ask" action, in which case the final wl_data_source.action
/// event will happen immediately before wl_data_source.dnd_finished.
/// Compositors may also change the selected action on the fly, mainly
/// in response to keyboard modifier changes during the drag-and-drop
/// operation.
/// The most recent action received is always the valid one. The chosen
/// action may change alongside negotiation (e.g. an "ask" action can turn
/// into a "move" operation), so the effects of the final action must
/// always be applied in wl_data_offer.dnd_finished.
/// Clients can trigger cursor surface changes from this point, so
/// they reflect the current action.
pub const Action = struct {
dnd_action: DataDeviceManagerDndAction,
pub const since_version = 3;
pub const opcode: u16 = 5;
};
};
/// error
pub const Error = error{
InvalidActionMask,
InvalidSource,
} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.InvalidActionMask,
1 => Error.InvalidSource,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.InvalidActionMask => 0,
Error.InvalidSource => 1,
else => null,
};
}
pub const error_invalid_action_mask_since_version = 1;
pub const error_invalid_source_since_version = 1;
pub fn marshal(data_source: DataSource, event: Event) void {
switch (event) {
.target => |target| {
if (!data_source.resource.client.wire.putUint(data_source.resource.id)) return;
if (!data_source.resource.client.wire.putUint(((@as(u32, 12 + @truncate(u32, target.mime_type.len)) << 16) & 0xffff0000) | (Event.Target.opcode & 0x0000ffff))) return;
if (!data_source.resource.client.wire.putString(target.mime_type)) return;
},
.send => |send| {
if (!data_source.resource.client.wire.putUint(data_source.resource.id)) return;
if (!data_source.resource.client.wire.putUint(((@as(u32, 12 + @truncate(u32, send.mime_type.len)) << 16) & 0xffff0000) | (Event.Send.opcode & 0x0000ffff))) return;
if (!data_source.resource.client.wire.putString(send.mime_type)) return;
if (!data_source.resource.client.wire.putFd(send.fd)) return;
},
.cancelled => |cancelled| {
if (!data_source.resource.client.wire.putUint(data_source.resource.id)) return;
if (!data_source.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.Cancelled.opcode & 0x0000ffff))) return;
},
.dnd_drop_performed => |dnd_drop_performed| {
if (!data_source.resource.client.wire.putUint(data_source.resource.id)) return;
if (!data_source.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.DndDropPerformed.opcode & 0x0000ffff))) return;
},
.dnd_finished => |dnd_finished| {
if (!data_source.resource.client.wire.putUint(data_source.resource.id)) return;
if (!data_source.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.DndFinished.opcode & 0x0000ffff))) return;
},
.action => |action| {
if (!data_source.resource.client.wire.putUint(data_source.resource.id)) return;
if (!data_source.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Action.opcode & 0x0000ffff))) return;
if (!data_source.resource.client.wire.putUint(action.dnd_action)) return;
},
}
}
pub fn unmarshal(data_source: DataSource, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Offer.opcode => {
var offer: Request.Offer = undefined;
if (p.len < 4) return null;
offer.mime_type = @import("std").mem.bytesAsSlice([]const u8, p)[0];
p = p[@sizeOf([]const u8)..];
return @as(Request, .{ .offer = offer });
},
Request.Destroy.opcode => {
var destroy: Request.Destroy = undefined;
return @as(Request, .{ .destroy = destroy });
},
Request.SetActions.opcode => {
var set_actions: Request.SetActions = undefined;
if (p.len < 4) return null;
set_actions.dnd_actions = @import("std").mem.bytesAsSlice(DataDeviceManagerDndAction, p)[0];
p = p[@sizeOf(DataDeviceManagerDndAction)..];
return @as(Request, .{ .set_actions = set_actions });
},
else => return null,
}
}
};
/// wl_data_device: data transfer device
///
/// There is one wl_data_device per seat which can be obtained
/// from the global wl_data_device_manager singleton.
/// A wl_data_device provides access to inter-client data transfer
/// mechanisms such as copy-and-paste and drag-and-drop.
pub const DataDevice = struct {
resource: wayland.server.Resource,
pub fn version(data_device: DataDevice) u32 {
return data_device.resource.version();
}
pub fn data(data_device: DataDevice, comptime T: type) ?*T {
return data_device.resource.data(T);
}
pub const interface_version = 3;
pub const Request = union(enum) {
start_drag: StartDrag,
set_selection: SetSelection,
release: Release,
/// start_drag: start drag-and-drop operation
///
/// This request asks the compositor to start a drag-and-drop
/// operation on behalf of the client.
/// The source argument is the data source that provides the data
/// for the eventual data transfer. If source is NULL, enter, leave
/// and motion events are sent only to the client that initiated the
/// drag and the client is expected to handle the data passing
/// internally.
/// The origin surface is the surface where the drag originates and
/// the client must have an active implicit grab that matches the
/// serial.
/// The icon surface is an optional (can be NULL) surface that
/// provides an icon to be moved around with the cursor. Initially,
/// the top-left corner of the icon surface is placed at the cursor
/// hotspot, but subsequent wl_surface.attach request can move the
/// relative position. Attach requests must be confirmed with
/// wl_surface.commit as usual. The icon surface is given the role of
/// a drag-and-drop icon. If the icon surface already has another role,
/// it raises a protocol error.
/// The current and pending input regions of the icon wl_surface are
/// cleared, and wl_surface.set_input_region is ignored until the
/// wl_surface is no longer used as the icon surface. When the use
/// as an icon ends, the current and pending input regions become
/// undefined, and the wl_surface is unmapped.
pub const StartDrag = struct {
source: ?DataSource,
origin: Surface,
icon: ?Surface,
serial: u32,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// set_selection: copy data to the selection
///
/// This request asks the compositor to set the selection
/// to the data from the source on behalf of the client.
/// To unset the selection, set the source to NULL.
pub const SetSelection = struct {
source: ?DataSource,
serial: u32,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
/// release: destroy data device
///
/// This request destroys the data device.
pub const Release = struct {
pub const since_version = 2;
pub const opcode: u16 = 2;
pub const destructor = true;
};
};
pub const Event = union(enum) {
data_offer: DataOffer,
enter: Enter,
leave: Leave,
motion: Motion,
drop: Drop,
selection: Selection,
/// data_offer: introduce a new wl_data_offer
///
/// The data_offer event introduces a new wl_data_offer object,
/// which will subsequently be used in either the
/// data_device.enter event (for drag-and-drop) or the
/// data_device.selection event (for selections). Immediately
/// following the data_device_data_offer event, the new data_offer
/// object will send out data_offer.offer events to describe the
/// mime types it offers.
pub const DataOffer = struct {
id: DataOffer,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// enter: initiate drag-and-drop session
///
/// This event is sent when an active drag-and-drop pointer enters
/// a surface owned by the client. The position of the pointer at
/// enter time is provided by the x and y arguments, in surface-local
/// coordinates.
pub const Enter = struct {
serial: u32,
surface: Surface,
x: wayland.Fixed,
y: wayland.Fixed,
id: ?DataOffer,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
/// leave: end drag-and-drop session
///
/// This event is sent when the drag-and-drop pointer leaves the
/// surface and the session ends. The client must destroy the
/// wl_data_offer introduced at enter time at this point.
pub const Leave = struct {
pub const since_version = 1;
pub const opcode: u16 = 2;
};
/// motion: drag-and-drop session motion
///
/// This event is sent when the drag-and-drop pointer moves within
/// the currently focused surface. The new position of the pointer
/// is provided by the x and y arguments, in surface-local
/// coordinates.
pub const Motion = struct {
time: u32,
x: wayland.Fixed,
y: wayland.Fixed,
pub const since_version = 1;
pub const opcode: u16 = 3;
};
/// drop: end drag-and-drop session successfully
///
/// The event is sent when a drag-and-drop operation is ended
/// because the implicit grab is removed.
/// The drag-and-drop destination is expected to honor the last action
/// received through wl_data_offer.action, if the resulting action is
/// "copy" or "move", the destination can still perform
/// wl_data_offer.receive requests, and is expected to end all
/// transfers with a wl_data_offer.finish request.
/// If the resulting action is "ask", the action will not be considered
/// final. The drag-and-drop destination is expected to perform one last
/// wl_data_offer.set_actions request, or wl_data_offer.destroy in order
/// to cancel the operation.
pub const Drop = struct {
pub const since_version = 1;
pub const opcode: u16 = 4;
};
/// selection: advertise new selection
///
/// The selection event is sent out to notify the client of a new
/// wl_data_offer for the selection for this device. The
/// data_device.data_offer and the data_offer.offer events are
/// sent out immediately before this event to introduce the data
/// offer object. The selection event is sent to a client
/// immediately before receiving keyboard focus and when a new
/// selection is set while the client has keyboard focus. The
/// data_offer is valid until a new data_offer or NULL is received
/// or until the client loses keyboard focus. The client must
/// destroy the previous selection data_offer, if any, upon receiving
/// this event.
pub const Selection = struct {
id: ?DataOffer,
pub const since_version = 1;
pub const opcode: u16 = 5;
};
};
/// error
pub const Error = error{Role} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.Role,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.Role => 0,
else => null,
};
}
pub const error_role_since_version = 1;
pub fn marshal(data_device: DataDevice, event: Event) void {
switch (event) {
.data_offer => |data_offer| {
if (!data_device.resource.client.wire.putUint(data_device.resource.id)) return;
if (!data_device.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.DataOffer.opcode & 0x0000ffff))) return;
if (!data_device.resource.client.wire.putUint(data_offer.id.resource.id)) return;
},
.enter => |enter| {
if (!data_device.resource.client.wire.putUint(data_device.resource.id)) return;
if (!data_device.resource.client.wire.putUint(((@as(u32, 20) << 16) & 0xffff0000) | (Event.Enter.opcode & 0x0000ffff))) return;
if (!data_device.resource.client.wire.putUint(enter.serial)) return;
if (!data_device.resource.client.wire.putUint(enter.surface.resource.id)) return;
if (!data_device.resource.client.wire.putFixed(enter.x)) return;
if (!data_device.resource.client.wire.putFixed(enter.y)) return;
if (!data_device.resource.client.wire.putUint(enter.id.resource.id)) return;
},
.leave => |leave| {
if (!data_device.resource.client.wire.putUint(data_device.resource.id)) return;
if (!data_device.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.Leave.opcode & 0x0000ffff))) return;
},
.motion => |motion| {
if (!data_device.resource.client.wire.putUint(data_device.resource.id)) return;
if (!data_device.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Motion.opcode & 0x0000ffff))) return;
if (!data_device.resource.client.wire.putUint(motion.time)) return;
if (!data_device.resource.client.wire.putFixed(motion.x)) return;
if (!data_device.resource.client.wire.putFixed(motion.y)) return;
},
.drop => |drop| {
if (!data_device.resource.client.wire.putUint(data_device.resource.id)) return;
if (!data_device.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.Drop.opcode & 0x0000ffff))) return;
},
.selection => |selection| {
if (!data_device.resource.client.wire.putUint(data_device.resource.id)) return;
if (!data_device.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Selection.opcode & 0x0000ffff))) return;
if (!data_device.resource.client.wire.putUint(selection.id.resource.id)) return;
},
}
}
pub fn unmarshal(data_device: DataDevice, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.StartDrag.opcode => {
var start_drag: Request.StartDrag = undefined;
if (p.len < 4) return null;
start_drag.serial = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
return @as(Request, .{ .start_drag = start_drag });
},
Request.SetSelection.opcode => {
var set_selection: Request.SetSelection = undefined;
if (p.len < 4) return null;
set_selection.serial = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
return @as(Request, .{ .set_selection = set_selection });
},
Request.Release.opcode => {
var release: Request.Release = undefined;
return @as(Request, .{ .release = release });
},
else => return null,
}
}
};
/// wl_data_device_manager: data transfer interface
///
/// The wl_data_device_manager is a singleton global object that
/// provides access to inter-client data transfer mechanisms such as
/// copy-and-paste and drag-and-drop. These mechanisms are tied to
/// a wl_seat and this interface lets a client get a wl_data_device
/// corresponding to a wl_seat.
/// Depending on the version bound, the objects created from the bound
/// wl_data_device_manager object will have different requirements for
/// functioning properly. See wl_data_source.set_actions,
/// wl_data_offer.accept and wl_data_offer.finish for details.
pub const DataDeviceManager = struct {
resource: wayland.server.Resource,
pub fn version(data_device_manager: DataDeviceManager) u32 {
return data_device_manager.resource.version();
}
pub fn data(data_device_manager: DataDeviceManager, comptime T: type) ?*T {
return data_device_manager.resource.data(T);
}
pub const interface_version = 3;
pub const Request = union(enum) {
create_data_source: CreateDataSource,
get_data_device: GetDataDevice,
/// create_data_source: create a new data source
///
/// Create a new data source.
pub const CreateDataSource = struct {
id: DataSource,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// get_data_device: create a new data device
///
/// Create a new data device for a given seat.
pub const GetDataDevice = struct {
id: DataDevice,
seat: Seat,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
};
pub const Event = union(enum) {};
/// dnd_action: drag and drop actions
///
/// This is a bitmask of the available/preferred actions in a
/// drag-and-drop operation.
/// In the compositor, the selected action is a result of matching the
/// actions offered by the source and destination sides. "action" events
/// with a "none" action will be sent to both source and destination if
/// there is no match. All further checks will effectively happen on
/// (source actions ∩ destination actions).
/// In addition, compositors may also pick different actions in
/// reaction to key modifiers being pressed. One common design that
/// is used in major toolkits (and the behavior recommended for
/// compositors) is:
/// - If no modifiers are pressed, the first match (in bit order)
/// will be used.
/// - Pressing Shift selects "move", if enabled in the mask.
/// - Pressing Control selects "copy", if enabled in the mask.
/// Behavior beyond that is considered implementation-dependent.
/// Compositors may for example bind other modifiers (like Alt/Meta)
/// or drags initiated with other buttons than BTN_LEFT to specific
/// actions (e.g. "ask").
pub const DndAction = packed struct {
none: bool,
copy: bool,
move: bool,
ask: bool,
pub const none_since_version = 1;
pub const copy_since_version = 1;
pub const move_since_version = 1;
pub const ask_since_version = 1;
pub fn fromInt(i: u32) DndAction {
return .{
.none = i & 0 != 0,
.copy = i & 1 != 0,
.move = i & 2 != 0,
.ask = i & 4 != 0,
};
}
pub fn toInt(e: DndAction) u32 {
return 0 |
@boolToInt(e.none) * 0 |
@boolToInt(e.copy) * 1 |
@boolToInt(e.move) * 2 |
@boolToInt(e.ask) * 4;
}
pub const since_version = 3;
};
pub fn marshal(data_device_manager: DataDeviceManager, event: Event) void {
switch (event) {}
}
pub fn unmarshal(data_device_manager: DataDeviceManager, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.CreateDataSource.opcode => {
var create_data_source: Request.CreateDataSource = undefined;
return @as(Request, .{ .create_data_source = create_data_source });
},
Request.GetDataDevice.opcode => {
var get_data_device: Request.GetDataDevice = undefined;
return @as(Request, .{ .get_data_device = get_data_device });
},
else => return null,
}
}
};
/// wl_shell: create desktop-style surfaces
///
/// This interface is implemented by servers that provide
/// desktop-style user interfaces.
/// It allows clients to associate a wl_shell_surface with
/// a basic surface.
/// Note! This protocol is deprecated and not intended for production use.
/// For desktop-style user interfaces, use xdg_shell.
pub const Shell = struct {
resource: wayland.server.Resource,
pub fn version(shell: Shell) u32 {
return shell.resource.version();
}
pub fn data(shell: Shell, comptime T: type) ?*T {
return shell.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
get_shell_surface: GetShellSurface,
/// get_shell_surface: create a shell surface from a surface
///
/// Create a shell surface for an existing surface. This gives
/// the wl_surface the role of a shell surface. If the wl_surface
/// already has another role, it raises a protocol error.
/// Only one shell surface can be associated with a given surface.
pub const GetShellSurface = struct {
id: ShellSurface,
surface: Surface,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
};
pub const Event = union(enum) {};
/// error
pub const Error = error{Role} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.Role,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.Role => 0,
else => null,
};
}
pub const error_role_since_version = 1;
pub fn marshal(shell: Shell, event: Event) void {
switch (event) {}
}
pub fn unmarshal(shell: Shell, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.GetShellSurface.opcode => {
var get_shell_surface: Request.GetShellSurface = undefined;
return @as(Request, .{ .get_shell_surface = get_shell_surface });
},
else => return null,
}
}
};
/// wl_shell_surface: desktop-style metadata interface
///
/// An interface that may be implemented by a wl_surface, for
/// implementations that provide a desktop-style user interface.
/// It provides requests to treat surfaces like toplevel, fullscreen
/// or popup windows, move, resize or maximize them, associate
/// metadata like title and class, etc.
/// On the server side the object is automatically destroyed when
/// the related wl_surface is destroyed. On the client side,
/// wl_shell_surface_destroy() must be called before destroying
/// the wl_surface object.
pub const ShellSurface = struct {
resource: wayland.server.Resource,
pub fn version(shell_surface: ShellSurface) u32 {
return shell_surface.resource.version();
}
pub fn data(shell_surface: ShellSurface, comptime T: type) ?*T {
return shell_surface.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
pong: Pong,
move: Move,
resize: Resize,
set_toplevel: SetToplevel,
set_transient: SetTransient,
set_fullscreen: SetFullscreen,
set_popup: SetPopup,
set_maximized: SetMaximized,
set_title: SetTitle,
set_class: SetClass,
/// pong: respond to a ping event
///
/// A client must respond to a ping event with a pong request or
/// the client may be deemed unresponsive.
pub const Pong = struct {
serial: u32,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// move: start an interactive move
///
/// Start a pointer-driven move of the surface.
/// This request must be used in response to a button press event.
/// The server may ignore move requests depending on the state of
/// the surface (e.g. fullscreen or maximized).
pub const Move = struct {
seat: Seat,
serial: u32,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
/// resize: start an interactive resize
///
/// Start a pointer-driven resizing of the surface.
/// This request must be used in response to a button press event.
/// The server may ignore resize requests depending on the state of
/// the surface (e.g. fullscreen or maximized).
pub const Resize = struct {
seat: Seat,
serial: u32,
edges: Resize,
pub const since_version = 1;
pub const opcode: u16 = 2;
pub const destructor = false;
};
/// set_toplevel: make the surface a toplevel surface
///
/// Map the surface as a toplevel surface.
/// A toplevel surface is not fullscreen, maximized or transient.
pub const SetToplevel = struct {
pub const since_version = 1;
pub const opcode: u16 = 3;
pub const destructor = false;
};
/// set_transient: make the surface a transient surface
///
/// Map the surface relative to an existing surface.
/// The x and y arguments specify the location of the upper left
/// corner of the surface relative to the upper left corner of the
/// parent surface, in surface-local coordinates.
/// The flags argument controls details of the transient behaviour.
pub const SetTransient = struct {
parent: Surface,
x: i32,
y: i32,
flags: Transient,
pub const since_version = 1;
pub const opcode: u16 = 4;
pub const destructor = false;
};
/// set_fullscreen: make the surface a fullscreen surface
///
/// Map the surface as a fullscreen surface.
/// If an output parameter is given then the surface will be made
/// fullscreen on that output. If the client does not specify the
/// output then the compositor will apply its policy - usually
/// choosing the output on which the surface has the biggest surface
/// area.
/// The client may specify a method to resolve a size conflict
/// between the output size and the surface size - this is provided
/// through the method parameter.
/// The framerate parameter is used only when the method is set
/// to "driver", to indicate the preferred framerate. A value of 0
/// indicates that the client does not care about framerate. The
/// framerate is specified in mHz, that is framerate of 60000 is 60Hz.
/// A method of "scale" or "driver" implies a scaling operation of
/// the surface, either via a direct scaling operation or a change of
/// the output mode. This will override any kind of output scaling, so
/// that mapping a surface with a buffer size equal to the mode can
/// fill the screen independent of buffer_scale.
/// A method of "fill" means we don't scale up the buffer, however
/// any output scale is applied. This means that you may run into
/// an edge case where the application maps a buffer with the same
/// size of the output mode but buffer_scale 1 (thus making a
/// surface larger than the output). In this case it is allowed to
/// downscale the results to fit the screen.
/// The compositor must reply to this request with a configure event
/// with the dimensions for the output on which the surface will
/// be made fullscreen.
pub const SetFullscreen = struct {
method: FullscreenMethod,
framerate: u32,
output: ?Output,
pub const since_version = 1;
pub const opcode: u16 = 5;
pub const destructor = false;
};
/// set_popup: make the surface a popup surface
///
/// Map the surface as a popup.
/// A popup surface is a transient surface with an added pointer
/// grab.
/// An existing implicit grab will be changed to owner-events mode,
/// and the popup grab will continue after the implicit grab ends
/// (i.e. releasing the mouse button does not cause the popup to
/// be unmapped).
/// The popup grab continues until the window is destroyed or a
/// mouse button is pressed in any other client's window. A click
/// in any of the client's surfaces is reported as normal, however,
/// clicks in other clients' surfaces will be discarded and trigger
/// the callback.
/// The x and y arguments specify the location of the upper left
/// corner of the surface relative to the upper left corner of the
/// parent surface, in surface-local coordinates.
pub const SetPopup = struct {
seat: Seat,
serial: u32,
parent: Surface,
x: i32,
y: i32,
flags: Transient,
pub const since_version = 1;
pub const opcode: u16 = 6;
pub const destructor = false;
};
/// set_maximized: make the surface a maximized surface
///
/// Map the surface as a maximized surface.
/// If an output parameter is given then the surface will be
/// maximized on that output. If the client does not specify the
/// output then the compositor will apply its policy - usually
/// choosing the output on which the surface has the biggest surface
/// area.
/// The compositor will reply with a configure event telling
/// the expected new surface size. The operation is completed
/// on the next buffer attach to this surface.
/// A maximized surface typically fills the entire output it is
/// bound to, except for desktop elements such as panels. This is
/// the main difference between a maximized shell surface and a
/// fullscreen shell surface.
/// The details depend on the compositor implementation.
pub const SetMaximized = struct {
output: ?Output,
pub const since_version = 1;
pub const opcode: u16 = 7;
pub const destructor = false;
};
/// set_title: set surface title
///
/// Set a short title for the surface.
/// This string may be used to identify the surface in a task bar,
/// window list, or other user interface elements provided by the
/// compositor.
/// The string must be encoded in UTF-8.
pub const SetTitle = struct {
title: []const u8,
pub const since_version = 1;
pub const opcode: u16 = 8;
pub const destructor = false;
};
/// set_class: set surface class
///
/// Set a class for the surface.
/// The surface class identifies the general class of applications
/// to which the surface belongs. A common convention is to use the
/// file name (or the full path if it is a non-standard location) of
/// the application's .desktop file as the class.
pub const SetClass = struct {
class_: []const u8,
pub const since_version = 1;
pub const opcode: u16 = 9;
pub const destructor = false;
};
};
pub const Event = union(enum) {
ping: Ping,
configure: Configure,
popup_done: PopupDone,
/// ping: ping client
///
/// Ping a client to check if it is receiving events and sending
/// requests. A client is expected to reply with a pong request.
pub const Ping = struct {
serial: u32,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// configure: suggest resize
///
/// The configure event asks the client to resize its surface.
/// The size is a hint, in the sense that the client is free to
/// ignore it if it doesn't resize, pick a smaller size (to
/// satisfy aspect ratio or resize in steps of NxM pixels).
/// The edges parameter provides a hint about how the surface
/// was resized. The client may use this information to decide
/// how to adjust its content to the new size (e.g. a scrolling
/// area might adjust its content position to leave the viewable
/// content unmoved).
/// The client is free to dismiss all but the last configure
/// event it received.
/// The width and height arguments specify the size of the window
/// in surface-local coordinates.
pub const Configure = struct {
edges: Resize,
width: i32,
height: i32,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
/// popup_done: popup interaction is done
///
/// The popup_done event is sent out when a popup grab is broken,
/// that is, when the user clicks a surface that doesn't belong
/// to the client owning the popup surface.
pub const PopupDone = struct {
pub const since_version = 1;
pub const opcode: u16 = 2;
};
};
/// resize: edge values for resizing
///
/// These values are used to indicate which edge of a surface
/// is being dragged in a resize operation. The server may
/// use this information to adapt its behavior, e.g. choose
/// an appropriate cursor image.
pub const Resize = packed struct {
none: bool,
top: bool,
bottom: bool,
left: bool,
top_left: bool,
bottom_left: bool,
right: bool,
top_right: bool,
bottom_right: bool,
pub const none_since_version = 1;
pub const top_since_version = 1;
pub const bottom_since_version = 1;
pub const left_since_version = 1;
pub const top_left_since_version = 1;
pub const bottom_left_since_version = 1;
pub const right_since_version = 1;
pub const top_right_since_version = 1;
pub const bottom_right_since_version = 1;
pub fn fromInt(i: u32) Resize {
return .{
.none = i & 0 != 0,
.top = i & 1 != 0,
.bottom = i & 2 != 0,
.left = i & 4 != 0,
.top_left = i & 5 != 0,
.bottom_left = i & 6 != 0,
.right = i & 8 != 0,
.top_right = i & 9 != 0,
.bottom_right = i & 10 != 0,
};
}
pub fn toInt(e: Resize) u32 {
return 0 |
@boolToInt(e.none) * 0 |
@boolToInt(e.top) * 1 |
@boolToInt(e.bottom) * 2 |
@boolToInt(e.left) * 4 |
@boolToInt(e.top_left) * 5 |
@boolToInt(e.bottom_left) * 6 |
@boolToInt(e.right) * 8 |
@boolToInt(e.top_right) * 9 |
@boolToInt(e.bottom_right) * 10;
}
pub const since_version = 1;
};
/// transient: details of transient behaviour
///
/// These flags specify details of the expected behaviour
/// of transient surfaces. Used in the set_transient request.
pub const Transient = packed struct {
inactive: bool,
pub const inactive_since_version = 1;
pub fn fromInt(i: u32) Transient {
return .{
.inactive = i & 0x1 != 0,
};
}
pub fn toInt(e: Transient) u32 {
return 0 |
@boolToInt(e.inactive) * 0x1;
}
pub const since_version = 1;
};
/// fullscreen_method: different method to set the surface fullscreen
///
/// Hints to indicate to the compositor how to deal with a conflict
/// between the dimensions of the surface and the dimensions of the
/// output. The compositor is free to ignore this parameter.
pub const FullscreenMethod = enum(u32) {
default = 0,
scale = 1,
driver = 2,
fill = 3,
pub const default_since_version = 1;
pub const scale_since_version = 1;
pub const driver_since_version = 1;
pub const fill_since_version = 1;
pub fn fromInt(i: u32) FullscreenMethod {
return @intToEnum(FullscreenMethod, i);
}
pub fn toInt(e: FullscreenMethod) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
pub fn marshal(shell_surface: ShellSurface, event: Event) void {
switch (event) {
.ping => |ping| {
if (!shell_surface.resource.client.wire.putUint(shell_surface.resource.id)) return;
if (!shell_surface.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Ping.opcode & 0x0000ffff))) return;
if (!shell_surface.resource.client.wire.putUint(ping.serial)) return;
},
.configure => |configure| {
if (!shell_surface.resource.client.wire.putUint(shell_surface.resource.id)) return;
if (!shell_surface.resource.client.wire.putUint(((@as(u32, 20) << 16) & 0xffff0000) | (Event.Configure.opcode & 0x0000ffff))) return;
if (!shell_surface.resource.client.wire.putUint(configure.edges)) return;
if (!shell_surface.resource.client.wire.putInt(configure.width)) return;
if (!shell_surface.resource.client.wire.putInt(configure.height)) return;
},
.popup_done => |popup_done| {
if (!shell_surface.resource.client.wire.putUint(shell_surface.resource.id)) return;
if (!shell_surface.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.PopupDone.opcode & 0x0000ffff))) return;
},
}
}
pub fn unmarshal(shell_surface: ShellSurface, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Pong.opcode => {
var pong: Request.Pong = undefined;
if (p.len < 4) return null;
pong.serial = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
return @as(Request, .{ .pong = pong });
},
Request.Move.opcode => {
var move: Request.Move = undefined;
if (p.len < 4) return null;
move.serial = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
return @as(Request, .{ .move = move });
},
Request.Resize.opcode => {
var resize: Request.Resize = undefined;
if (p.len < 4) return null;
resize.serial = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
if (p.len < 4) return null;
resize.edges = @import("std").mem.bytesAsSlice(Resize, p)[0];
p = p[@sizeOf(Resize)..];
return @as(Request, .{ .resize = resize });
},
Request.SetToplevel.opcode => {
var set_toplevel: Request.SetToplevel = undefined;
return @as(Request, .{ .set_toplevel = set_toplevel });
},
Request.SetTransient.opcode => {
var set_transient: Request.SetTransient = undefined;
if (p.len < 4) return null;
set_transient.x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
set_transient.y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
set_transient.flags = @import("std").mem.bytesAsSlice(Transient, p)[0];
p = p[@sizeOf(Transient)..];
return @as(Request, .{ .set_transient = set_transient });
},
Request.SetFullscreen.opcode => {
var set_fullscreen: Request.SetFullscreen = undefined;
if (p.len < 4) return null;
set_fullscreen.method = @import("std").mem.bytesAsSlice(FullscreenMethod, p)[0];
p = p[@sizeOf(FullscreenMethod)..];
if (p.len < 4) return null;
set_fullscreen.framerate = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
return @as(Request, .{ .set_fullscreen = set_fullscreen });
},
Request.SetPopup.opcode => {
var set_popup: Request.SetPopup = undefined;
if (p.len < 4) return null;
set_popup.serial = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
if (p.len < 4) return null;
set_popup.x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
set_popup.y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
set_popup.flags = @import("std").mem.bytesAsSlice(Transient, p)[0];
p = p[@sizeOf(Transient)..];
return @as(Request, .{ .set_popup = set_popup });
},
Request.SetMaximized.opcode => {
var set_maximized: Request.SetMaximized = undefined;
return @as(Request, .{ .set_maximized = set_maximized });
},
Request.SetTitle.opcode => {
var set_title: Request.SetTitle = undefined;
if (p.len < 4) return null;
set_title.title = @import("std").mem.bytesAsSlice([]const u8, p)[0];
p = p[@sizeOf([]const u8)..];
return @as(Request, .{ .set_title = set_title });
},
Request.SetClass.opcode => {
var set_class: Request.SetClass = undefined;
if (p.len < 4) return null;
set_class.class_ = @import("std").mem.bytesAsSlice([]const u8, p)[0];
p = p[@sizeOf([]const u8)..];
return @as(Request, .{ .set_class = set_class });
},
else => return null,
}
}
};
/// wl_surface: an onscreen surface
///
/// A surface is a rectangular area that may be displayed on zero
/// or more outputs, and shown any number of times at the compositor's
/// discretion. They can present wl_buffers, receive user input, and
/// define a local coordinate system.
/// The size of a surface (and relative positions on it) is described
/// in surface-local coordinates, which may differ from the buffer
/// coordinates of the pixel content, in case a buffer_transform
/// or a buffer_scale is used.
/// A surface without a "role" is fairly useless: a compositor does
/// not know where, when or how to present it. The role is the
/// purpose of a wl_surface. Examples of roles are a cursor for a
/// pointer (as set by wl_pointer.set_cursor), a drag icon
/// (wl_data_device.start_drag), a sub-surface
/// (wl_subcompositor.get_subsurface), and a window as defined by a
/// shell protocol (e.g. wl_shell.get_shell_surface).
/// A surface can have only one role at a time. Initially a
/// wl_surface does not have a role. Once a wl_surface is given a
/// role, it is set permanently for the whole lifetime of the
/// wl_surface object. Giving the current role again is allowed,
/// unless explicitly forbidden by the relevant interface
/// specification.
/// Surface roles are given by requests in other interfaces such as
/// wl_pointer.set_cursor. The request should explicitly mention
/// that this request gives a role to a wl_surface. Often, this
/// request also creates a new protocol object that represents the
/// role and adds additional functionality to wl_surface. When a
/// client wants to destroy a wl_surface, they must destroy this 'role
/// object' before the wl_surface.
/// Destroying the role object does not remove the role from the
/// wl_surface, but it may stop the wl_surface from "playing the role".
/// For instance, if a wl_subsurface object is destroyed, the wl_surface
/// it was created for will be unmapped and forget its position and
/// z-order. It is allowed to create a wl_subsurface for the same
/// wl_surface again, but it is not allowed to use the wl_surface as
/// a cursor (cursor is a different role than sub-surface, and role
/// switching is not allowed).
pub const Surface = struct {
resource: wayland.server.Resource,
pub fn version(surface: Surface) u32 {
return surface.resource.version();
}
pub fn data(surface: Surface, comptime T: type) ?*T {
return surface.resource.data(T);
}
pub const interface_version = 4;
pub const Request = union(enum) {
destroy: Destroy,
attach: Attach,
damage: Damage,
frame: Frame,
set_opaque_region: SetOpaqueRegion,
set_input_region: SetInputRegion,
commit: Commit,
set_buffer_transform: SetBufferTransform,
set_buffer_scale: SetBufferScale,
damage_buffer: DamageBuffer,
/// destroy: delete surface
///
/// Deletes the surface and invalidates its object ID.
pub const Destroy = struct {
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = true;
};
/// attach: set the surface contents
///
/// Set a buffer as the content of this surface.
/// The new size of the surface is calculated based on the buffer
/// size transformed by the inverse buffer_transform and the
/// inverse buffer_scale. This means that the supplied buffer
/// must be an integer multiple of the buffer_scale.
/// The x and y arguments specify the location of the new pending
/// buffer's upper left corner, relative to the current buffer's upper
/// left corner, in surface-local coordinates. In other words, the
/// x and y, combined with the new surface size define in which
/// directions the surface's size changes.
/// Surface contents are double-buffered state, see wl_surface.commit.
/// The initial surface contents are void; there is no content.
/// wl_surface.attach assigns the given wl_buffer as the pending
/// wl_buffer. wl_surface.commit makes the pending wl_buffer the new
/// surface contents, and the size of the surface becomes the size
/// calculated from the wl_buffer, as described above. After commit,
/// there is no pending buffer until the next attach.
/// Committing a pending wl_buffer allows the compositor to read the
/// pixels in the wl_buffer. The compositor may access the pixels at
/// any time after the wl_surface.commit request. When the compositor
/// will not access the pixels anymore, it will send the
/// wl_buffer.release event. Only after receiving wl_buffer.release,
/// the client may reuse the wl_buffer. A wl_buffer that has been
/// attached and then replaced by another attach instead of committed
/// will not receive a release event, and is not used by the
/// compositor.
/// If a pending wl_buffer has been committed to more than one wl_surface,
/// the delivery of wl_buffer.release events becomes undefined. A well
/// behaved client should not rely on wl_buffer.release events in this
/// case. Alternatively, a client could create multiple wl_buffer objects
/// from the same backing storage or use wp_linux_buffer_release.
/// Destroying the wl_buffer after wl_buffer.release does not change
/// the surface contents. However, if the client destroys the
/// wl_buffer before receiving the wl_buffer.release event, the surface
/// contents become undefined immediately.
/// If wl_surface.attach is sent with a NULL wl_buffer, the
/// following wl_surface.commit will remove the surface content.
pub const Attach = struct {
buffer: ?Buffer,
x: i32,
y: i32,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
/// damage: mark part of the surface damaged
///
/// This request is used to describe the regions where the pending
/// buffer is different from the current surface contents, and where
/// the surface therefore needs to be repainted. The compositor
/// ignores the parts of the damage that fall outside of the surface.
/// Damage is double-buffered state, see wl_surface.commit.
/// The damage rectangle is specified in surface-local coordinates,
/// where x and y specify the upper left corner of the damage rectangle.
/// The initial value for pending damage is empty: no damage.
/// wl_surface.damage adds pending damage: the new pending damage
/// is the union of old pending damage and the given rectangle.
/// wl_surface.commit assigns pending damage as the current damage,
/// and clears pending damage. The server will clear the current
/// damage as it repaints the surface.
/// Note! New clients should not use this request. Instead damage can be
/// posted with wl_surface.damage_buffer which uses buffer coordinates
/// instead of surface coordinates.
pub const Damage = struct {
x: i32,
y: i32,
width: i32,
height: i32,
pub const since_version = 1;
pub const opcode: u16 = 2;
pub const destructor = false;
};
/// frame: request a frame throttling hint
///
/// Request a notification when it is a good time to start drawing a new
/// frame, by creating a frame callback. This is useful for throttling
/// redrawing operations, and driving animations.
/// When a client is animating on a wl_surface, it can use the 'frame'
/// request to get notified when it is a good time to draw and commit the
/// next frame of animation. If the client commits an update earlier than
/// that, it is likely that some updates will not make it to the display,
/// and the client is wasting resources by drawing too often.
/// The frame request will take effect on the next wl_surface.commit.
/// The notification will only be posted for one frame unless
/// requested again. For a wl_surface, the notifications are posted in
/// the order the frame requests were committed.
/// The server must send the notifications so that a client
/// will not send excessive updates, while still allowing
/// the highest possible update rate for clients that wait for the reply
/// before drawing again. The server should give some time for the client
/// to draw and commit after sending the frame callback events to let it
/// hit the next output refresh.
/// A server should avoid signaling the frame callbacks if the
/// surface is not visible in any way, e.g. the surface is off-screen,
/// or completely obscured by other opaque surfaces.
/// The object returned by this request will be destroyed by the
/// compositor after the callback is fired and as such the client must not
/// attempt to use it after that point.
/// The callback_data passed in the callback is the current time, in
/// milliseconds, with an undefined base.
pub const Frame = struct {
callback: Callback,
pub const since_version = 1;
pub const opcode: u16 = 3;
pub const destructor = false;
};
/// set_opaque_region: set opaque region
///
/// This request sets the region of the surface that contains
/// opaque content.
/// The opaque region is an optimization hint for the compositor
/// that lets it optimize the redrawing of content behind opaque
/// regions. Setting an opaque region is not required for correct
/// behaviour, but marking transparent content as opaque will result
/// in repaint artifacts.
/// The opaque region is specified in surface-local coordinates.
/// The compositor ignores the parts of the opaque region that fall
/// outside of the surface.
/// Opaque region is double-buffered state, see wl_surface.commit.
/// wl_surface.set_opaque_region changes the pending opaque region.
/// wl_surface.commit copies the pending region to the current region.
/// Otherwise, the pending and current regions are never changed.
/// The initial value for an opaque region is empty. Setting the pending
/// opaque region has copy semantics, and the wl_region object can be
/// destroyed immediately. A NULL wl_region causes the pending opaque
/// region to be set to empty.
pub const SetOpaqueRegion = struct {
region: ?Region,
pub const since_version = 1;
pub const opcode: u16 = 4;
pub const destructor = false;
};
/// set_input_region: set input region
///
/// This request sets the region of the surface that can receive
/// pointer and touch events.
/// Input events happening outside of this region will try the next
/// surface in the server surface stack. The compositor ignores the
/// parts of the input region that fall outside of the surface.
/// The input region is specified in surface-local coordinates.
/// Input region is double-buffered state, see wl_surface.commit.
/// wl_surface.set_input_region changes the pending input region.
/// wl_surface.commit copies the pending region to the current region.
/// Otherwise the pending and current regions are never changed,
/// except cursor and icon surfaces are special cases, see
/// wl_pointer.set_cursor and wl_data_device.start_drag.
/// The initial value for an input region is infinite. That means the
/// whole surface will accept input. Setting the pending input region
/// has copy semantics, and the wl_region object can be destroyed
/// immediately. A NULL wl_region causes the input region to be set
/// to infinite.
pub const SetInputRegion = struct {
region: ?Region,
pub const since_version = 1;
pub const opcode: u16 = 5;
pub const destructor = false;
};
/// commit: commit pending surface state
///
/// Surface state (input, opaque, and damage regions, attached buffers,
/// etc.) is double-buffered. Protocol requests modify the pending state,
/// as opposed to the current state in use by the compositor. A commit
/// request atomically applies all pending state, replacing the current
/// state. After commit, the new pending state is as documented for each
/// related request.
/// On commit, a pending wl_buffer is applied first, and all other state
/// second. This means that all coordinates in double-buffered state are
/// relative to the new wl_buffer coming into use, except for
/// wl_surface.attach itself. If there is no pending wl_buffer, the
/// coordinates are relative to the current surface contents.
/// All requests that need a commit to become effective are documented
/// to affect double-buffered state.
/// Other interfaces may add further double-buffered surface state.
pub const Commit = struct {
pub const since_version = 1;
pub const opcode: u16 = 6;
pub const destructor = false;
};
/// set_buffer_transform: sets the buffer transformation
///
/// This request sets an optional transformation on how the compositor
/// interprets the contents of the buffer attached to the surface. The
/// accepted values for the transform parameter are the values for
/// wl_output.transform.
/// Buffer transform is double-buffered state, see wl_surface.commit.
/// A newly created surface has its buffer transformation set to normal.
/// wl_surface.set_buffer_transform changes the pending buffer
/// transformation. wl_surface.commit copies the pending buffer
/// transformation to the current one. Otherwise, the pending and current
/// values are never changed.
/// The purpose of this request is to allow clients to render content
/// according to the output transform, thus permitting the compositor to
/// use certain optimizations even if the display is rotated. Using
/// hardware overlays and scanning out a client buffer for fullscreen
/// surfaces are examples of such optimizations. Those optimizations are
/// highly dependent on the compositor implementation, so the use of this
/// request should be considered on a case-by-case basis.
/// Note that if the transform value includes 90 or 270 degree rotation,
/// the width of the buffer will become the surface height and the height
/// of the buffer will become the surface width.
/// If transform is not one of the values from the
/// wl_output.transform enum the invalid_transform protocol error
/// is raised.
pub const SetBufferTransform = struct {
transform: OutputTransform,
pub const since_version = 2;
pub const opcode: u16 = 7;
pub const destructor = false;
};
/// set_buffer_scale: sets the buffer scaling factor
///
/// This request sets an optional scaling factor on how the compositor
/// interprets the contents of the buffer attached to the window.
/// Buffer scale is double-buffered state, see wl_surface.commit.
/// A newly created surface has its buffer scale set to 1.
/// wl_surface.set_buffer_scale changes the pending buffer scale.
/// wl_surface.commit copies the pending buffer scale to the current one.
/// Otherwise, the pending and current values are never changed.
/// The purpose of this request is to allow clients to supply higher
/// resolution buffer data for use on high resolution outputs. It is
/// intended that you pick the same buffer scale as the scale of the
/// output that the surface is displayed on. This means the compositor
/// can avoid scaling when rendering the surface on that output.
/// Note that if the scale is larger than 1, then you have to attach
/// a buffer that is larger (by a factor of scale in each dimension)
/// than the desired surface size.
/// If scale is not positive the invalid_scale protocol error is
/// raised.
pub const SetBufferScale = struct {
scale: i32,
pub const since_version = 3;
pub const opcode: u16 = 8;
pub const destructor = false;
};
/// damage_buffer: mark part of the surface damaged using buffer coordinates
///
/// This request is used to describe the regions where the pending
/// buffer is different from the current surface contents, and where
/// the surface therefore needs to be repainted. The compositor
/// ignores the parts of the damage that fall outside of the surface.
/// Damage is double-buffered state, see wl_surface.commit.
/// The damage rectangle is specified in buffer coordinates,
/// where x and y specify the upper left corner of the damage rectangle.
/// The initial value for pending damage is empty: no damage.
/// wl_surface.damage_buffer adds pending damage: the new pending
/// damage is the union of old pending damage and the given rectangle.
/// wl_surface.commit assigns pending damage as the current damage,
/// and clears pending damage. The server will clear the current
/// damage as it repaints the surface.
/// This request differs from wl_surface.damage in only one way - it
/// takes damage in buffer coordinates instead of surface-local
/// coordinates. While this generally is more intuitive than surface
/// coordinates, it is especially desirable when using wp_viewport
/// or when a drawing library (like EGL) is unaware of buffer scale
/// and buffer transform.
/// Note: Because buffer transformation changes and damage requests may
/// be interleaved in the protocol stream, it is impossible to determine
/// the actual mapping between surface and buffer damage until
/// wl_surface.commit time. Therefore, compositors wishing to take both
/// kinds of damage into account will have to accumulate damage from the
/// two requests separately and only transform from one to the other
/// after receiving the wl_surface.commit.
pub const DamageBuffer = struct {
x: i32,
y: i32,
width: i32,
height: i32,
pub const since_version = 4;
pub const opcode: u16 = 9;
pub const destructor = false;
};
};
pub const Event = union(enum) {
enter: Enter,
leave: Leave,
/// enter: surface enters an output
///
/// This is emitted whenever a surface's creation, movement, or resizing
/// results in some part of it being within the scanout region of an
/// output.
/// Note that a surface may be overlapping with zero or more outputs.
pub const Enter = struct {
output: Output,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// leave: surface leaves an output
///
/// This is emitted whenever a surface's creation, movement, or resizing
/// results in it no longer having any part of it within the scanout region
/// of an output.
pub const Leave = struct {
output: Output,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
};
/// error: wl_surface error values
///
/// These errors can be emitted in response to wl_surface requests.
pub const Error = error{
InvalidScale,
InvalidTransform,
} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.InvalidScale,
1 => Error.InvalidTransform,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.InvalidScale => 0,
Error.InvalidTransform => 1,
else => null,
};
}
pub const error_invalid_scale_since_version = 1;
pub const error_invalid_transform_since_version = 1;
pub fn marshal(surface: Surface, event: Event) void {
switch (event) {
.enter => |enter| {
if (!surface.resource.client.wire.putUint(surface.resource.id)) return;
if (!surface.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Enter.opcode & 0x0000ffff))) return;
if (!surface.resource.client.wire.putUint(enter.output.resource.id)) return;
},
.leave => |leave| {
if (!surface.resource.client.wire.putUint(surface.resource.id)) return;
if (!surface.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Leave.opcode & 0x0000ffff))) return;
if (!surface.resource.client.wire.putUint(leave.output.resource.id)) return;
},
}
}
pub fn unmarshal(surface: Surface, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Destroy.opcode => {
var destroy: Request.Destroy = undefined;
return @as(Request, .{ .destroy = destroy });
},
Request.Attach.opcode => {
var attach: Request.Attach = undefined;
if (p.len < 4) return null;
attach.x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
attach.y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .attach = attach });
},
Request.Damage.opcode => {
var damage: Request.Damage = undefined;
if (p.len < 4) return null;
damage.x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
damage.y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
damage.width = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
damage.height = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .damage = damage });
},
Request.Frame.opcode => {
var frame: Request.Frame = undefined;
return @as(Request, .{ .frame = frame });
},
Request.SetOpaqueRegion.opcode => {
var set_opaque_region: Request.SetOpaqueRegion = undefined;
return @as(Request, .{ .set_opaque_region = set_opaque_region });
},
Request.SetInputRegion.opcode => {
var set_input_region: Request.SetInputRegion = undefined;
return @as(Request, .{ .set_input_region = set_input_region });
},
Request.Commit.opcode => {
var commit: Request.Commit = undefined;
return @as(Request, .{ .commit = commit });
},
Request.SetBufferTransform.opcode => {
var set_buffer_transform: Request.SetBufferTransform = undefined;
if (p.len < 4) return null;
set_buffer_transform.transform = @import("std").mem.bytesAsSlice(OutputTransform, p)[0];
p = p[@sizeOf(OutputTransform)..];
return @as(Request, .{ .set_buffer_transform = set_buffer_transform });
},
Request.SetBufferScale.opcode => {
var set_buffer_scale: Request.SetBufferScale = undefined;
if (p.len < 4) return null;
set_buffer_scale.scale = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .set_buffer_scale = set_buffer_scale });
},
Request.DamageBuffer.opcode => {
var damage_buffer: Request.DamageBuffer = undefined;
if (p.len < 4) return null;
damage_buffer.x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
damage_buffer.y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
damage_buffer.width = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
damage_buffer.height = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .damage_buffer = damage_buffer });
},
else => return null,
}
}
};
/// wl_seat: group of input devices
///
/// A seat is a group of keyboards, pointer and touch devices. This
/// object is published as a global during start up, or when such a
/// device is hot plugged. A seat typically has a pointer and
/// maintains a keyboard focus and a pointer focus.
pub const Seat = struct {
resource: wayland.server.Resource,
pub fn version(seat: Seat) u32 {
return seat.resource.version();
}
pub fn data(seat: Seat, comptime T: type) ?*T {
return seat.resource.data(T);
}
pub const interface_version = 7;
pub const Request = union(enum) {
get_pointer: GetPointer,
get_keyboard: GetKeyboard,
get_touch: GetTouch,
release: Release,
/// get_pointer: return pointer object
///
/// The ID provided will be initialized to the wl_pointer interface
/// for this seat.
/// This request only takes effect if the seat has the pointer
/// capability, or has had the pointer capability in the past.
/// It is a protocol violation to issue this request on a seat that has
/// never had the pointer capability.
pub const GetPointer = struct {
id: Pointer,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// get_keyboard: return keyboard object
///
/// The ID provided will be initialized to the wl_keyboard interface
/// for this seat.
/// This request only takes effect if the seat has the keyboard
/// capability, or has had the keyboard capability in the past.
/// It is a protocol violation to issue this request on a seat that has
/// never had the keyboard capability.
pub const GetKeyboard = struct {
id: Keyboard,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
/// get_touch: return touch object
///
/// The ID provided will be initialized to the wl_touch interface
/// for this seat.
/// This request only takes effect if the seat has the touch
/// capability, or has had the touch capability in the past.
/// It is a protocol violation to issue this request on a seat that has
/// never had the touch capability.
pub const GetTouch = struct {
id: Touch,
pub const since_version = 1;
pub const opcode: u16 = 2;
pub const destructor = false;
};
/// release: release the seat object
///
/// Using this request a client can tell the server that it is not going to
/// use the seat object anymore.
pub const Release = struct {
pub const since_version = 5;
pub const opcode: u16 = 3;
pub const destructor = true;
};
};
pub const Event = union(enum) {
capabilities: Capabilities,
name: Name,
/// capabilities: seat capabilities changed
///
/// This is emitted whenever a seat gains or loses the pointer,
/// keyboard or touch capabilities. The argument is a capability
/// enum containing the complete set of capabilities this seat has.
/// When the pointer capability is added, a client may create a
/// wl_pointer object using the wl_seat.get_pointer request. This object
/// will receive pointer events until the capability is removed in the
/// future.
/// When the pointer capability is removed, a client should destroy the
/// wl_pointer objects associated with the seat where the capability was
/// removed, using the wl_pointer.release request. No further pointer
/// events will be received on these objects.
/// In some compositors, if a seat regains the pointer capability and a
/// client has a previously obtained wl_pointer object of version 4 or
/// less, that object may start sending pointer events again. This
/// behavior is considered a misinterpretation of the intended behavior
/// and must not be relied upon by the client. wl_pointer objects of
/// version 5 or later must not send events if created before the most
/// recent event notifying the client of an added pointer capability.
/// The above behavior also applies to wl_keyboard and wl_touch with the
/// keyboard and touch capabilities, respectively.
pub const Capabilities = struct {
capabilities: Capability,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// name: unique identifier for this seat
///
/// In a multiseat configuration this can be used by the client to help
/// identify which physical devices the seat represents. Based on
/// the seat configuration used by the compositor.
pub const Name = struct {
name: []const u8,
pub const since_version = 2;
pub const opcode: u16 = 1;
};
};
/// capability: seat capability bitmask
///
/// This is a bitmask of capabilities this seat has; if a member is
/// set, then it is present on the seat.
pub const Capability = packed struct {
pointer: bool,
keyboard: bool,
touch: bool,
pub const pointer_since_version = 1;
pub const keyboard_since_version = 1;
pub const touch_since_version = 1;
pub fn fromInt(i: u32) Capability {
return .{
.pointer = i & 1 != 0,
.keyboard = i & 2 != 0,
.touch = i & 4 != 0,
};
}
pub fn toInt(e: Capability) u32 {
return 0 |
@boolToInt(e.pointer) * 1 |
@boolToInt(e.keyboard) * 2 |
@boolToInt(e.touch) * 4;
}
pub const since_version = 1;
};
pub fn marshal(seat: Seat, event: Event) void {
switch (event) {
.capabilities => |capabilities| {
if (!seat.resource.client.wire.putUint(seat.resource.id)) return;
if (!seat.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Capabilities.opcode & 0x0000ffff))) return;
if (!seat.resource.client.wire.putUint(capabilities.capabilities)) return;
},
.name => |name| {
if (!seat.resource.client.wire.putUint(seat.resource.id)) return;
if (!seat.resource.client.wire.putUint(((@as(u32, 12 + @truncate(u32, name.name.len)) << 16) & 0xffff0000) | (Event.Name.opcode & 0x0000ffff))) return;
if (!seat.resource.client.wire.putString(name.name)) return;
},
}
}
pub fn unmarshal(seat: Seat, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.GetPointer.opcode => {
var get_pointer: Request.GetPointer = undefined;
return @as(Request, .{ .get_pointer = get_pointer });
},
Request.GetKeyboard.opcode => {
var get_keyboard: Request.GetKeyboard = undefined;
return @as(Request, .{ .get_keyboard = get_keyboard });
},
Request.GetTouch.opcode => {
var get_touch: Request.GetTouch = undefined;
return @as(Request, .{ .get_touch = get_touch });
},
Request.Release.opcode => {
var release: Request.Release = undefined;
return @as(Request, .{ .release = release });
},
else => return null,
}
}
};
/// wl_pointer: pointer input device
///
/// The wl_pointer interface represents one or more input devices,
/// such as mice, which control the pointer location and pointer_focus
/// of a seat.
/// The wl_pointer interface generates motion, enter and leave
/// events for the surfaces that the pointer is located over,
/// and button and axis events for button presses, button releases
/// and scrolling.
pub const Pointer = struct {
resource: wayland.server.Resource,
pub fn version(pointer: Pointer) u32 {
return pointer.resource.version();
}
pub fn data(pointer: Pointer, comptime T: type) ?*T {
return pointer.resource.data(T);
}
pub const interface_version = 7;
pub const Request = union(enum) {
set_cursor: SetCursor,
release: Release,
/// set_cursor: set the pointer surface
///
/// Set the pointer surface, i.e., the surface that contains the
/// pointer image (cursor). This request gives the surface the role
/// of a cursor. If the surface already has another role, it raises
/// a protocol error.
/// The cursor actually changes only if the pointer
/// focus for this device is one of the requesting client's surfaces
/// or the surface parameter is the current pointer surface. If
/// there was a previous surface set with this request it is
/// replaced. If surface is NULL, the pointer image is hidden.
/// The parameters hotspot_x and hotspot_y define the position of
/// the pointer surface relative to the pointer location. Its
/// top-left corner is always at (x, y) - (hotspot_x, hotspot_y),
/// where (x, y) are the coordinates of the pointer location, in
/// surface-local coordinates.
/// On surface.attach requests to the pointer surface, hotspot_x
/// and hotspot_y are decremented by the x and y parameters
/// passed to the request. Attach must be confirmed by
/// wl_surface.commit as usual.
/// The hotspot can also be updated by passing the currently set
/// pointer surface to this request with new values for hotspot_x
/// and hotspot_y.
/// The current and pending input regions of the wl_surface are
/// cleared, and wl_surface.set_input_region is ignored until the
/// wl_surface is no longer used as the cursor. When the use as a
/// cursor ends, the current and pending input regions become
/// undefined, and the wl_surface is unmapped.
pub const SetCursor = struct {
serial: u32,
surface: ?Surface,
hotspot_x: i32,
hotspot_y: i32,
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = false;
};
/// release: release the pointer object
///
/// Using this request a client can tell the server that it is not going to
/// use the pointer object anymore.
/// This request destroys the pointer proxy object, so clients must not call
/// wl_pointer_destroy() after using this request.
pub const Release = struct {
pub const since_version = 3;
pub const opcode: u16 = 1;
pub const destructor = true;
};
};
pub const Event = union(enum) {
enter: Enter,
leave: Leave,
motion: Motion,
button: Button,
axis: Axis,
frame: Frame,
axis_source: AxisSource,
axis_stop: AxisStop,
axis_discrete: AxisDiscrete,
/// enter: enter event
///
/// Notification that this seat's pointer is focused on a certain
/// surface.
/// When a seat's focus enters a surface, the pointer image
/// is undefined and a client should respond to this event by setting
/// an appropriate pointer image with the set_cursor request.
pub const Enter = struct {
serial: u32,
surface: Surface,
surface_x: wayland.Fixed,
surface_y: wayland.Fixed,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// leave: leave event
///
/// Notification that this seat's pointer is no longer focused on
/// a certain surface.
/// The leave notification is sent before the enter notification
/// for the new focus.
pub const Leave = struct {
serial: u32,
surface: Surface,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
/// motion: pointer motion event
///
/// Notification of pointer location change. The arguments
/// surface_x and surface_y are the location relative to the
/// focused surface.
pub const Motion = struct {
time: u32,
surface_x: wayland.Fixed,
surface_y: wayland.Fixed,
pub const since_version = 1;
pub const opcode: u16 = 2;
};
/// button: pointer button event
///
/// Mouse button click and release notifications.
/// The location of the click is given by the last motion or
/// enter event.
/// The time argument is a timestamp with millisecond
/// granularity, with an undefined base.
/// The button is a button code as defined in the Linux kernel's
/// linux/input-event-codes.h header file, e.g. BTN_LEFT.
/// Any 16-bit button code value is reserved for future additions to the
/// kernel's event code list. All other button codes above 0xFFFF are
/// currently undefined but may be used in future versions of this
/// protocol.
pub const Button = struct {
serial: u32,
time: u32,
button: u32,
state: ButtonState,
pub const since_version = 1;
pub const opcode: u16 = 3;
};
/// axis: axis event
///
/// Scroll and other axis notifications.
/// For scroll events (vertical and horizontal scroll axes), the
/// value parameter is the length of a vector along the specified
/// axis in a coordinate space identical to those of motion events,
/// representing a relative movement along the specified axis.
/// For devices that support movements non-parallel to axes multiple
/// axis events will be emitted.
/// When applicable, for example for touch pads, the server can
/// choose to emit scroll events where the motion vector is
/// equivalent to a motion event vector.
/// When applicable, a client can transform its content relative to the
/// scroll distance.
pub const Axis = struct {
time: u32,
axis: Axis,
value: wayland.Fixed,
pub const since_version = 1;
pub const opcode: u16 = 4;
};
/// frame: end of a pointer event sequence
///
/// Indicates the end of a set of events that logically belong together.
/// A client is expected to accumulate the data in all events within the
/// frame before proceeding.
/// All wl_pointer events before a wl_pointer.frame event belong
/// logically together. For example, in a diagonal scroll motion the
/// compositor will send an optional wl_pointer.axis_source event, two
/// wl_pointer.axis events (horizontal and vertical) and finally a
/// wl_pointer.frame event. The client may use this information to
/// calculate a diagonal vector for scrolling.
/// When multiple wl_pointer.axis events occur within the same frame,
/// the motion vector is the combined motion of all events.
/// When a wl_pointer.axis and a wl_pointer.axis_stop event occur within
/// the same frame, this indicates that axis movement in one axis has
/// stopped but continues in the other axis.
/// When multiple wl_pointer.axis_stop events occur within the same
/// frame, this indicates that these axes stopped in the same instance.
/// A wl_pointer.frame event is sent for every logical event group,
/// even if the group only contains a single wl_pointer event.
/// Specifically, a client may get a sequence: motion, frame, button,
/// frame, axis, frame, axis_stop, frame.
/// The wl_pointer.enter and wl_pointer.leave events are logical events
/// generated by the compositor and not the hardware. These events are
/// also grouped by a wl_pointer.frame. When a pointer moves from one
/// surface to another, a compositor should group the
/// wl_pointer.leave event within the same wl_pointer.frame.
/// However, a client must not rely on wl_pointer.leave and
/// wl_pointer.enter being in the same wl_pointer.frame.
/// Compositor-specific policies may require the wl_pointer.leave and
/// wl_pointer.enter event being split across multiple wl_pointer.frame
/// groups.
pub const Frame = struct {
pub const since_version = 5;
pub const opcode: u16 = 5;
};
/// axis_source: axis source event
///
/// Source information for scroll and other axes.
/// This event does not occur on its own. It is sent before a
/// wl_pointer.frame event and carries the source information for
/// all events within that frame.
/// The source specifies how this event was generated. If the source is
/// wl_pointer.axis_source.finger, a wl_pointer.axis_stop event will be
/// sent when the user lifts the finger off the device.
/// If the source is wl_pointer.axis_source.wheel,
/// wl_pointer.axis_source.wheel_tilt or
/// wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event may
/// or may not be sent. Whether a compositor sends an axis_stop event
/// for these sources is hardware-specific and implementation-dependent;
/// clients must not rely on receiving an axis_stop event for these
/// scroll sources and should treat scroll sequences from these scroll
/// sources as unterminated by default.
/// This event is optional. If the source is unknown for a particular
/// axis event sequence, no event is sent.
/// Only one wl_pointer.axis_source event is permitted per frame.
/// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
/// not guaranteed.
pub const AxisSource = struct {
axis_source: AxisSource,
pub const since_version = 5;
pub const opcode: u16 = 6;
};
/// axis_stop: axis stop event
///
/// Stop notification for scroll and other axes.
/// For some wl_pointer.axis_source types, a wl_pointer.axis_stop event
/// is sent to notify a client that the axis sequence has terminated.
/// This enables the client to implement kinetic scrolling.
/// See the wl_pointer.axis_source documentation for information on when
/// this event may be generated.
/// Any wl_pointer.axis events with the same axis_source after this
/// event should be considered as the start of a new axis motion.
/// The timestamp is to be interpreted identical to the timestamp in the
/// wl_pointer.axis event. The timestamp value may be the same as a
/// preceding wl_pointer.axis event.
pub const AxisStop = struct {
time: u32,
axis: Axis,
pub const since_version = 5;
pub const opcode: u16 = 7;
};
/// axis_discrete: axis click event
///
/// Discrete step information for scroll and other axes.
/// This event carries the axis value of the wl_pointer.axis event in
/// discrete steps (e.g. mouse wheel clicks).
/// This event does not occur on its own, it is coupled with a
/// wl_pointer.axis event that represents this axis value on a
/// continuous scale. The protocol guarantees that each axis_discrete
/// event is always followed by exactly one axis event with the same
/// axis number within the same wl_pointer.frame. Note that the protocol
/// allows for other events to occur between the axis_discrete and
/// its coupled axis event, including other axis_discrete or axis
/// events.
/// This event is optional; continuous scrolling devices
/// like two-finger scrolling on touchpads do not have discrete
/// steps and do not generate this event.
/// The discrete value carries the directional information. e.g. a value
/// of -2 is two steps towards the negative direction of this axis.
/// The axis number is identical to the axis number in the associated
/// axis event.
/// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
/// not guaranteed.
pub const AxisDiscrete = struct {
axis: Axis,
discrete: i32,
pub const since_version = 5;
pub const opcode: u16 = 8;
};
};
/// error
pub const Error = error{Role} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.Role,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.Role => 0,
else => null,
};
}
pub const error_role_since_version = 1;
/// button_state: physical button state
///
/// Describes the physical state of a button that produced the button
/// event.
pub const ButtonState = enum(u32) {
released = 0,
pressed = 1,
pub const released_since_version = 1;
pub const pressed_since_version = 1;
pub fn fromInt(i: u32) ButtonState {
return @intToEnum(ButtonState, i);
}
pub fn toInt(e: ButtonState) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
/// axis: axis types
///
/// Describes the axis types of scroll events.
pub const Axis = enum(u32) {
vertical_scroll = 0,
horizontal_scroll = 1,
pub const vertical_scroll_since_version = 1;
pub const horizontal_scroll_since_version = 1;
pub fn fromInt(i: u32) Axis {
return @intToEnum(Axis, i);
}
pub fn toInt(e: Axis) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
/// axis_source: axis source types
///
/// Describes the source types for axis events. This indicates to the
/// client how an axis event was physically generated; a client may
/// adjust the user interface accordingly. For example, scroll events
/// from a "finger" source may be in a smooth coordinate space with
/// kinetic scrolling whereas a "wheel" source may be in discrete steps
/// of a number of lines.
/// The "continuous" axis source is a device generating events in a
/// continuous coordinate space, but using something other than a
/// finger. One example for this source is button-based scrolling where
/// the vertical motion of a device is converted to scroll events while
/// a button is held down.
/// The "wheel tilt" axis source indicates that the actual device is a
/// wheel but the scroll event is not caused by a rotation but a
/// (usually sideways) tilt of the wheel.
pub const AxisSource = enum(u32) {
wheel = 0,
finger = 1,
continuous = 2,
wheel_tilt = 3,
pub const wheel_since_version = 1;
pub const finger_since_version = 1;
pub const continuous_since_version = 1;
pub const wheel_tilt_since_version = 6;
pub fn fromInt(i: u32) AxisSource {
return @intToEnum(AxisSource, i);
}
pub fn toInt(e: AxisSource) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
pub fn marshal(pointer: Pointer, event: Event) void {
switch (event) {
.enter => |enter| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.Enter.opcode & 0x0000ffff))) return;
if (!pointer.resource.client.wire.putUint(enter.serial)) return;
if (!pointer.resource.client.wire.putUint(enter.surface.resource.id)) return;
if (!pointer.resource.client.wire.putFixed(enter.surface_x)) return;
if (!pointer.resource.client.wire.putFixed(enter.surface_y)) return;
},
.leave => |leave| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.Leave.opcode & 0x0000ffff))) return;
if (!pointer.resource.client.wire.putUint(leave.serial)) return;
if (!pointer.resource.client.wire.putUint(leave.surface.resource.id)) return;
},
.motion => |motion| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Motion.opcode & 0x0000ffff))) return;
if (!pointer.resource.client.wire.putUint(motion.time)) return;
if (!pointer.resource.client.wire.putFixed(motion.surface_x)) return;
if (!pointer.resource.client.wire.putFixed(motion.surface_y)) return;
},
.button => |button| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 24) << 16) & 0xffff0000) | (Event.Button.opcode & 0x0000ffff))) return;
if (!pointer.resource.client.wire.putUint(button.serial)) return;
if (!pointer.resource.client.wire.putUint(button.time)) return;
if (!pointer.resource.client.wire.putUint(button.button)) return;
if (!pointer.resource.client.wire.putUint(button.state)) return;
},
.axis => |axis| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.Axis.opcode & 0x0000ffff))) return;
if (!pointer.resource.client.wire.putUint(axis.time)) return;
if (!pointer.resource.client.wire.putUint(axis.axis)) return;
if (!pointer.resource.client.wire.putFixed(axis.value)) return;
},
.frame => |frame| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.Frame.opcode & 0x0000ffff))) return;
},
.axis_source => |axis_source| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.AxisSource.opcode & 0x0000ffff))) return;
if (!pointer.resource.client.wire.putUint(axis_source.axis_source)) return;
},
.axis_stop => |axis_stop| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.AxisStop.opcode & 0x0000ffff))) return;
if (!pointer.resource.client.wire.putUint(axis_stop.time)) return;
if (!pointer.resource.client.wire.putUint(axis_stop.axis)) return;
},
.axis_discrete => |axis_discrete| {
if (!pointer.resource.client.wire.putUint(pointer.resource.id)) return;
if (!pointer.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.AxisDiscrete.opcode & 0x0000ffff))) return;
if (!pointer.resource.client.wire.putUint(axis_discrete.axis)) return;
if (!pointer.resource.client.wire.putInt(axis_discrete.discrete)) return;
},
}
}
pub fn unmarshal(pointer: Pointer, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.SetCursor.opcode => {
var set_cursor: Request.SetCursor = undefined;
if (p.len < 4) return null;
set_cursor.serial = @import("std").mem.bytesAsSlice(u32, p)[0];
p = p[@sizeOf(u32)..];
if (p.len < 4) return null;
set_cursor.hotspot_x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
set_cursor.hotspot_y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .set_cursor = set_cursor });
},
Request.Release.opcode => {
var release: Request.Release = undefined;
return @as(Request, .{ .release = release });
},
else => return null,
}
}
};
/// wl_keyboard: keyboard input device
///
/// The wl_keyboard interface represents one or more keyboards
/// associated with a seat.
pub const Keyboard = struct {
resource: wayland.server.Resource,
pub fn version(keyboard: Keyboard) u32 {
return keyboard.resource.version();
}
pub fn data(keyboard: Keyboard, comptime T: type) ?*T {
return keyboard.resource.data(T);
}
pub const interface_version = 7;
pub const Request = union(enum) {
release: Release,
/// release: release the keyboard object
pub const Release = struct {
pub const since_version = 3;
pub const opcode: u16 = 0;
pub const destructor = true;
};
};
pub const Event = union(enum) {
keymap: Keymap,
enter: Enter,
leave: Leave,
key: Key,
modifiers: Modifiers,
repeat_info: RepeatInfo,
/// keymap: keyboard mapping
///
/// This event provides a file descriptor to the client which can be
/// memory-mapped to provide a keyboard mapping description.
/// From version 7 onwards, the fd must be mapped with MAP_PRIVATE by
/// the recipient, as MAP_SHARED may fail.
pub const Keymap = struct {
format: KeymapFormat,
fd: c_int,
size: u32,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// enter: enter event
///
/// Notification that this seat's keyboard focus is on a certain
/// surface.
pub const Enter = struct {
serial: u32,
surface: Surface,
keys: []const u8,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
/// leave: leave event
///
/// Notification that this seat's keyboard focus is no longer on
/// a certain surface.
/// The leave notification is sent before the enter notification
/// for the new focus.
pub const Leave = struct {
serial: u32,
surface: Surface,
pub const since_version = 1;
pub const opcode: u16 = 2;
};
/// key: key event
///
/// A key was pressed or released.
/// The time argument is a timestamp with millisecond
/// granularity, with an undefined base.
pub const Key = struct {
serial: u32,
time: u32,
key: u32,
state: KeyState,
pub const since_version = 1;
pub const opcode: u16 = 3;
};
/// modifiers: modifier and group state
///
/// Notifies clients that the modifier and/or group state has
/// changed, and it should update its local state.
pub const Modifiers = struct {
serial: u32,
mods_depressed: u32,
mods_latched: u32,
mods_locked: u32,
group: u32,
pub const since_version = 1;
pub const opcode: u16 = 4;
};
/// repeat_info: repeat rate and delay
///
/// Informs the client about the keyboard's repeat rate and delay.
/// This event is sent as soon as the wl_keyboard object has been created,
/// and is guaranteed to be received by the client before any key press
/// event.
/// Negative values for either rate or delay are illegal. A rate of zero
/// will disable any repeating (regardless of the value of delay).
/// This event can be sent later on as well with a new value if necessary,
/// so clients should continue listening for the event past the creation
/// of wl_keyboard.
pub const RepeatInfo = struct {
rate: i32,
delay: i32,
pub const since_version = 4;
pub const opcode: u16 = 5;
};
};
/// keymap_format: keyboard mapping format
///
/// This specifies the format of the keymap provided to the
/// client with the wl_keyboard.keymap event.
pub const KeymapFormat = enum(u32) {
no_keymap = 0,
xkb_v_1 = 1,
pub const no_keymap_since_version = 1;
pub const xkb_v_1_since_version = 1;
pub fn fromInt(i: u32) KeymapFormat {
return @intToEnum(KeymapFormat, i);
}
pub fn toInt(e: KeymapFormat) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
/// key_state: physical key state
///
/// Describes the physical state of a key that produced the key event.
pub const KeyState = enum(u32) {
released = 0,
pressed = 1,
pub const released_since_version = 1;
pub const pressed_since_version = 1;
pub fn fromInt(i: u32) KeyState {
return @intToEnum(KeyState, i);
}
pub fn toInt(e: KeyState) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
pub fn marshal(keyboard: Keyboard, event: Event) void {
switch (event) {
.keymap => |keymap| {
if (!keyboard.resource.client.wire.putUint(keyboard.resource.id)) return;
if (!keyboard.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.Keymap.opcode & 0x0000ffff))) return;
if (!keyboard.resource.client.wire.putUint(keymap.format)) return;
if (!keyboard.resource.client.wire.putFd(keymap.fd)) return;
if (!keyboard.resource.client.wire.putUint(keymap.size)) return;
},
.enter => |enter| {
if (!keyboard.resource.client.wire.putUint(keyboard.resource.id)) return;
if (!keyboard.resource.client.wire.putUint(((@as(u32, 20 + @truncate(u32, enter.keys.len)) << 16) & 0xffff0000) | (Event.Enter.opcode & 0x0000ffff))) return;
if (!keyboard.resource.client.wire.putUint(enter.serial)) return;
if (!keyboard.resource.client.wire.putUint(enter.surface.resource.id)) return;
if (!keyboard.resource.client.wire.putArray(enter.keys)) return;
},
.leave => |leave| {
if (!keyboard.resource.client.wire.putUint(keyboard.resource.id)) return;
if (!keyboard.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.Leave.opcode & 0x0000ffff))) return;
if (!keyboard.resource.client.wire.putUint(leave.serial)) return;
if (!keyboard.resource.client.wire.putUint(leave.surface.resource.id)) return;
},
.key => |key| {
if (!keyboard.resource.client.wire.putUint(keyboard.resource.id)) return;
if (!keyboard.resource.client.wire.putUint(((@as(u32, 24) << 16) & 0xffff0000) | (Event.Key.opcode & 0x0000ffff))) return;
if (!keyboard.resource.client.wire.putUint(key.serial)) return;
if (!keyboard.resource.client.wire.putUint(key.time)) return;
if (!keyboard.resource.client.wire.putUint(key.key)) return;
if (!keyboard.resource.client.wire.putUint(key.state)) return;
},
.modifiers => |modifiers| {
if (!keyboard.resource.client.wire.putUint(keyboard.resource.id)) return;
if (!keyboard.resource.client.wire.putUint(((@as(u32, 28) << 16) & 0xffff0000) | (Event.Modifiers.opcode & 0x0000ffff))) return;
if (!keyboard.resource.client.wire.putUint(modifiers.serial)) return;
if (!keyboard.resource.client.wire.putUint(modifiers.mods_depressed)) return;
if (!keyboard.resource.client.wire.putUint(modifiers.mods_latched)) return;
if (!keyboard.resource.client.wire.putUint(modifiers.mods_locked)) return;
if (!keyboard.resource.client.wire.putUint(modifiers.group)) return;
},
.repeat_info => |repeat_info| {
if (!keyboard.resource.client.wire.putUint(keyboard.resource.id)) return;
if (!keyboard.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.RepeatInfo.opcode & 0x0000ffff))) return;
if (!keyboard.resource.client.wire.putInt(repeat_info.rate)) return;
if (!keyboard.resource.client.wire.putInt(repeat_info.delay)) return;
},
}
}
pub fn unmarshal(keyboard: Keyboard, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Release.opcode => {
var release: Request.Release = undefined;
return @as(Request, .{ .release = release });
},
else => return null,
}
}
};
/// wl_touch: touchscreen input device
///
/// The wl_touch interface represents a touchscreen
/// associated with a seat.
/// Touch interactions can consist of one or more contacts.
/// For each contact, a series of events is generated, starting
/// with a down event, followed by zero or more motion events,
/// and ending with an up event. Events relating to the same
/// contact point can be identified by the ID of the sequence.
pub const Touch = struct {
resource: wayland.server.Resource,
pub fn version(touch: Touch) u32 {
return touch.resource.version();
}
pub fn data(touch: Touch, comptime T: type) ?*T {
return touch.resource.data(T);
}
pub const interface_version = 7;
pub const Request = union(enum) {
release: Release,
/// release: release the touch object
pub const Release = struct {
pub const since_version = 3;
pub const opcode: u16 = 0;
pub const destructor = true;
};
};
pub const Event = union(enum) {
down: Down,
up: Up,
motion: Motion,
frame: Frame,
cancel: Cancel,
shape: Shape,
orientation: Orientation,
/// down: touch down event and beginning of a touch sequence
///
/// A new touch point has appeared on the surface. This touch point is
/// assigned a unique ID. Future events from this touch point reference
/// this ID. The ID ceases to be valid after a touch up event and may be
/// reused in the future.
pub const Down = struct {
serial: u32,
time: u32,
surface: Surface,
id: i32,
x: wayland.Fixed,
y: wayland.Fixed,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// up: end of a touch event sequence
///
/// The touch point has disappeared. No further events will be sent for
/// this touch point and the touch point's ID is released and may be
/// reused in a future touch down event.
pub const Up = struct {
serial: u32,
time: u32,
id: i32,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
/// motion: update of touch point coordinates
///
/// A touch point has changed coordinates.
pub const Motion = struct {
time: u32,
id: i32,
x: wayland.Fixed,
y: wayland.Fixed,
pub const since_version = 1;
pub const opcode: u16 = 2;
};
/// frame: end of touch frame event
///
/// Indicates the end of a set of events that logically belong together.
/// A client is expected to accumulate the data in all events within the
/// frame before proceeding.
/// A wl_touch.frame terminates at least one event but otherwise no
/// guarantee is provided about the set of events within a frame. A client
/// must assume that any state not updated in a frame is unchanged from the
/// previously known state.
pub const Frame = struct {
pub const since_version = 1;
pub const opcode: u16 = 3;
};
/// cancel: touch session cancelled
///
/// Sent if the compositor decides the touch stream is a global
/// gesture. No further events are sent to the clients from that
/// particular gesture. Touch cancellation applies to all touch points
/// currently active on this client's surface. The client is
/// responsible for finalizing the touch points, future touch points on
/// this surface may reuse the touch point ID.
pub const Cancel = struct {
pub const since_version = 1;
pub const opcode: u16 = 4;
};
/// shape: update shape of touch point
///
/// Sent when a touchpoint has changed its shape.
/// This event does not occur on its own. It is sent before a
/// wl_touch.frame event and carries the new shape information for
/// any previously reported, or new touch points of that frame.
/// Other events describing the touch point such as wl_touch.down,
/// wl_touch.motion or wl_touch.orientation may be sent within the
/// same wl_touch.frame. A client should treat these events as a single
/// logical touch point update. The order of wl_touch.shape,
/// wl_touch.orientation and wl_touch.motion is not guaranteed.
/// A wl_touch.down event is guaranteed to occur before the first
/// wl_touch.shape event for this touch ID but both events may occur within
/// the same wl_touch.frame.
/// A touchpoint shape is approximated by an ellipse through the major and
/// minor axis length. The major axis length describes the longer diameter
/// of the ellipse, while the minor axis length describes the shorter
/// diameter. Major and minor are orthogonal and both are specified in
/// surface-local coordinates. The center of the ellipse is always at the
/// touchpoint location as reported by wl_touch.down or wl_touch.move.
/// This event is only sent by the compositor if the touch device supports
/// shape reports. The client has to make reasonable assumptions about the
/// shape if it did not receive this event.
pub const Shape = struct {
id: i32,
major: wayland.Fixed,
minor: wayland.Fixed,
pub const since_version = 6;
pub const opcode: u16 = 5;
};
/// orientation: update orientation of touch point
///
/// Sent when a touchpoint has changed its orientation.
/// This event does not occur on its own. It is sent before a
/// wl_touch.frame event and carries the new shape information for
/// any previously reported, or new touch points of that frame.
/// Other events describing the touch point such as wl_touch.down,
/// wl_touch.motion or wl_touch.shape may be sent within the
/// same wl_touch.frame. A client should treat these events as a single
/// logical touch point update. The order of wl_touch.shape,
/// wl_touch.orientation and wl_touch.motion is not guaranteed.
/// A wl_touch.down event is guaranteed to occur before the first
/// wl_touch.orientation event for this touch ID but both events may occur
/// within the same wl_touch.frame.
/// The orientation describes the clockwise angle of a touchpoint's major
/// axis to the positive surface y-axis and is normalized to the -180 to
/// +180 degree range. The granularity of orientation depends on the touch
/// device, some devices only support binary rotation values between 0 and
/// 90 degrees.
/// This event is only sent by the compositor if the touch device supports
/// orientation reports.
pub const Orientation = struct {
id: i32,
orientation: wayland.Fixed,
pub const since_version = 6;
pub const opcode: u16 = 6;
};
};
pub fn marshal(touch: Touch, event: Event) void {
switch (event) {
.down => |down| {
if (!touch.resource.client.wire.putUint(touch.resource.id)) return;
if (!touch.resource.client.wire.putUint(((@as(u32, 24) << 16) & 0xffff0000) | (Event.Down.opcode & 0x0000ffff))) return;
if (!touch.resource.client.wire.putUint(down.serial)) return;
if (!touch.resource.client.wire.putUint(down.time)) return;
if (!touch.resource.client.wire.putUint(down.surface.resource.id)) return;
if (!touch.resource.client.wire.putInt(down.id)) return;
if (!touch.resource.client.wire.putFixed(down.x)) return;
if (!touch.resource.client.wire.putFixed(down.y)) return;
},
.up => |up| {
if (!touch.resource.client.wire.putUint(touch.resource.id)) return;
if (!touch.resource.client.wire.putUint(((@as(u32, 20) << 16) & 0xffff0000) | (Event.Up.opcode & 0x0000ffff))) return;
if (!touch.resource.client.wire.putUint(up.serial)) return;
if (!touch.resource.client.wire.putUint(up.time)) return;
if (!touch.resource.client.wire.putInt(up.id)) return;
},
.motion => |motion| {
if (!touch.resource.client.wire.putUint(touch.resource.id)) return;
if (!touch.resource.client.wire.putUint(((@as(u32, 16) << 16) & 0xffff0000) | (Event.Motion.opcode & 0x0000ffff))) return;
if (!touch.resource.client.wire.putUint(motion.time)) return;
if (!touch.resource.client.wire.putInt(motion.id)) return;
if (!touch.resource.client.wire.putFixed(motion.x)) return;
if (!touch.resource.client.wire.putFixed(motion.y)) return;
},
.frame => |frame| {
if (!touch.resource.client.wire.putUint(touch.resource.id)) return;
if (!touch.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.Frame.opcode & 0x0000ffff))) return;
},
.cancel => |cancel| {
if (!touch.resource.client.wire.putUint(touch.resource.id)) return;
if (!touch.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.Cancel.opcode & 0x0000ffff))) return;
},
.shape => |shape| {
if (!touch.resource.client.wire.putUint(touch.resource.id)) return;
if (!touch.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Shape.opcode & 0x0000ffff))) return;
if (!touch.resource.client.wire.putInt(shape.id)) return;
if (!touch.resource.client.wire.putFixed(shape.major)) return;
if (!touch.resource.client.wire.putFixed(shape.minor)) return;
},
.orientation => |orientation| {
if (!touch.resource.client.wire.putUint(touch.resource.id)) return;
if (!touch.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Orientation.opcode & 0x0000ffff))) return;
if (!touch.resource.client.wire.putInt(orientation.id)) return;
if (!touch.resource.client.wire.putFixed(orientation.orientation)) return;
},
}
}
pub fn unmarshal(touch: Touch, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Release.opcode => {
var release: Request.Release = undefined;
return @as(Request, .{ .release = release });
},
else => return null,
}
}
};
/// wl_output: compositor output region
///
/// An output describes part of the compositor geometry. The
/// compositor works in the 'compositor coordinate system' and an
/// output corresponds to a rectangular area in that space that is
/// actually visible. This typically corresponds to a monitor that
/// displays part of the compositor space. This object is published
/// as global during start up, or when a monitor is hotplugged.
pub const Output = struct {
resource: wayland.server.Resource,
pub fn version(output: Output) u32 {
return output.resource.version();
}
pub fn data(output: Output, comptime T: type) ?*T {
return output.resource.data(T);
}
pub const interface_version = 3;
pub const Request = union(enum) {
release: Release,
/// release: release the output object
///
/// Using this request a client can tell the server that it is not going to
/// use the output object anymore.
pub const Release = struct {
pub const since_version = 3;
pub const opcode: u16 = 0;
pub const destructor = true;
};
};
pub const Event = union(enum) {
geometry: Geometry,
mode: Mode,
done: Done,
scale: Scale,
/// geometry: properties of the output
///
/// The geometry event describes geometric properties of the output.
/// The event is sent when binding to the output object and whenever
/// any of the properties change.
/// The physical size can be set to zero if it doesn't make sense for this
/// output (e.g. for projectors or virtual outputs).
/// Note: wl_output only advertises partial information about the output
/// position and identification. Some compositors, for instance those not
/// implementing a desktop-style output layout or those exposing virtual
/// outputs, might fake this information. Instead of using x and y, clients
/// should use xdg_output.logical_position. Instead of using make and model,
/// clients should use xdg_output.name and xdg_output.description.
pub const Geometry = struct {
x: i32,
y: i32,
physical_width: i32,
physical_height: i32,
subpixel: Subpixel,
make: []const u8,
model: []const u8,
transform: Transform,
pub const since_version = 1;
pub const opcode: u16 = 0;
};
/// mode: advertise available modes for the output
///
/// The mode event describes an available mode for the output.
/// The event is sent when binding to the output object and there
/// will always be one mode, the current mode. The event is sent
/// again if an output changes mode, for the mode that is now
/// current. In other words, the current mode is always the last
/// mode that was received with the current flag set.
/// The size of a mode is given in physical hardware units of
/// the output device. This is not necessarily the same as
/// the output size in the global compositor space. For instance,
/// the output may be scaled, as described in wl_output.scale,
/// or transformed, as described in wl_output.transform. Clients
/// willing to retrieve the output size in the global compositor
/// space should use xdg_output.logical_size instead.
/// The vertical refresh rate can be set to zero if it doesn't make
/// sense for this output (e.g. for virtual outputs).
/// Clients should not use the refresh rate to schedule frames. Instead,
/// they should use the wl_surface.frame event or the presentation-time
/// protocol.
/// Note: this information is not always meaningful for all outputs. Some
/// compositors, such as those exposing virtual outputs, might fake the
/// refresh rate or the size.
pub const Mode = struct {
flags: Mode,
width: i32,
height: i32,
refresh: i32,
pub const since_version = 1;
pub const opcode: u16 = 1;
};
/// done: sent all information about output
///
/// This event is sent after all other properties have been
/// sent after binding to the output object and after any
/// other property changes done after that. This allows
/// changes to the output properties to be seen as
/// atomic, even if they happen via multiple events.
pub const Done = struct {
pub const since_version = 2;
pub const opcode: u16 = 2;
};
/// scale: output scaling properties
///
/// This event contains scaling geometry information
/// that is not in the geometry event. It may be sent after
/// binding the output object or if the output scale changes
/// later. If it is not sent, the client should assume a
/// scale of 1.
/// A scale larger than 1 means that the compositor will
/// automatically scale surface buffers by this amount
/// when rendering. This is used for very high resolution
/// displays where applications rendering at the native
/// resolution would be too small to be legible.
/// It is intended that scaling aware clients track the
/// current output of a surface, and if it is on a scaled
/// output it should use wl_surface.set_buffer_scale with
/// the scale of the output. That way the compositor can
/// avoid scaling the surface, and the client can supply
/// a higher detail image.
pub const Scale = struct {
factor: i32,
pub const since_version = 2;
pub const opcode: u16 = 3;
};
};
/// subpixel: subpixel geometry information
///
/// This enumeration describes how the physical
/// pixels on an output are laid out.
pub const Subpixel = enum(u32) {
unknown = 0,
none = 1,
horizontal_rgb = 2,
horizontal_bgr = 3,
vertical_rgb = 4,
vertical_bgr = 5,
pub const unknown_since_version = 1;
pub const none_since_version = 1;
pub const horizontal_rgb_since_version = 1;
pub const horizontal_bgr_since_version = 1;
pub const vertical_rgb_since_version = 1;
pub const vertical_bgr_since_version = 1;
pub fn fromInt(i: u32) Subpixel {
return @intToEnum(Subpixel, i);
}
pub fn toInt(e: Subpixel) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
/// transform: transform from framebuffer to output
///
/// This describes the transform that a compositor will apply to a
/// surface to compensate for the rotation or mirroring of an
/// output device.
/// The flipped values correspond to an initial flip around a
/// vertical axis followed by rotation.
/// The purpose is mainly to allow clients to render accordingly and
/// tell the compositor, so that for fullscreen surfaces, the
/// compositor will still be able to scan out directly from client
/// surfaces.
pub const Transform = enum(u32) {
normal = 0,
_90 = 1,
_180 = 2,
_270 = 3,
flipped = 4,
flipped_90 = 5,
flipped_180 = 6,
flipped_270 = 7,
pub const normal_since_version = 1;
pub const _90_since_version = 1;
pub const _180_since_version = 1;
pub const _270_since_version = 1;
pub const flipped_since_version = 1;
pub const flipped_90_since_version = 1;
pub const flipped_180_since_version = 1;
pub const flipped_270_since_version = 1;
pub fn fromInt(i: u32) Transform {
return @intToEnum(Transform, i);
}
pub fn toInt(e: Transform) u32 {
return @enumToInt(e);
}
pub const since_version = 1;
};
/// mode: mode information
///
/// These flags describe properties of an output mode.
/// They are used in the flags bitfield of the mode event.
pub const Mode = packed struct {
current: bool,
preferred: bool,
pub const current_since_version = 1;
pub const preferred_since_version = 1;
pub fn fromInt(i: u32) Mode {
return .{
.current = i & 0x1 != 0,
.preferred = i & 0x2 != 0,
};
}
pub fn toInt(e: Mode) u32 {
return 0 |
@boolToInt(e.current) * 0x1 |
@boolToInt(e.preferred) * 0x2;
}
pub const since_version = 1;
};
pub fn marshal(output: Output, event: Event) void {
switch (event) {
.geometry => |geometry| {
if (!output.resource.client.wire.putUint(output.resource.id)) return;
if (!output.resource.client.wire.putUint(((@as(u32, 40 + @truncate(u32, geometry.make.len) + @truncate(u32, geometry.model.len)) << 16) & 0xffff0000) | (Event.Geometry.opcode & 0x0000ffff))) return;
if (!output.resource.client.wire.putInt(geometry.x)) return;
if (!output.resource.client.wire.putInt(geometry.y)) return;
if (!output.resource.client.wire.putInt(geometry.physical_width)) return;
if (!output.resource.client.wire.putInt(geometry.physical_height)) return;
if (!output.resource.client.wire.putInt(geometry.subpixel)) return;
if (!output.resource.client.wire.putString(geometry.make)) return;
if (!output.resource.client.wire.putString(geometry.model)) return;
if (!output.resource.client.wire.putInt(geometry.transform)) return;
},
.mode => |mode| {
if (!output.resource.client.wire.putUint(output.resource.id)) return;
if (!output.resource.client.wire.putUint(((@as(u32, 24) << 16) & 0xffff0000) | (Event.Mode.opcode & 0x0000ffff))) return;
if (!output.resource.client.wire.putUint(mode.flags)) return;
if (!output.resource.client.wire.putInt(mode.width)) return;
if (!output.resource.client.wire.putInt(mode.height)) return;
if (!output.resource.client.wire.putInt(mode.refresh)) return;
},
.done => |done| {
if (!output.resource.client.wire.putUint(output.resource.id)) return;
if (!output.resource.client.wire.putUint(((@as(u32, 8) << 16) & 0xffff0000) | (Event.Done.opcode & 0x0000ffff))) return;
},
.scale => |scale| {
if (!output.resource.client.wire.putUint(output.resource.id)) return;
if (!output.resource.client.wire.putUint(((@as(u32, 12) << 16) & 0xffff0000) | (Event.Scale.opcode & 0x0000ffff))) return;
if (!output.resource.client.wire.putInt(scale.factor)) return;
},
}
}
pub fn unmarshal(output: Output, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Release.opcode => {
var release: Request.Release = undefined;
return @as(Request, .{ .release = release });
},
else => return null,
}
}
};
/// wl_region: region interface
///
/// A region object describes an area.
/// Region objects are used to describe the opaque and input
/// regions of a surface.
pub const Region = struct {
resource: wayland.server.Resource,
pub fn version(region: Region) u32 {
return region.resource.version();
}
pub fn data(region: Region, comptime T: type) ?*T {
return region.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
destroy: Destroy,
add: Add,
subtract: Subtract,
/// destroy: destroy region
///
/// Destroy the region. This will invalidate the object ID.
pub const Destroy = struct {
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = true;
};
/// add: add rectangle to region
///
/// Add the specified rectangle to the region.
pub const Add = struct {
x: i32,
y: i32,
width: i32,
height: i32,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
/// subtract: subtract rectangle from region
///
/// Subtract the specified rectangle from the region.
pub const Subtract = struct {
x: i32,
y: i32,
width: i32,
height: i32,
pub const since_version = 1;
pub const opcode: u16 = 2;
pub const destructor = false;
};
};
pub const Event = union(enum) {};
pub fn marshal(region: Region, event: Event) void {
switch (event) {}
}
pub fn unmarshal(region: Region, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Destroy.opcode => {
var destroy: Request.Destroy = undefined;
return @as(Request, .{ .destroy = destroy });
},
Request.Add.opcode => {
var add: Request.Add = undefined;
if (p.len < 4) return null;
add.x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
add.y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
add.width = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
add.height = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .add = add });
},
Request.Subtract.opcode => {
var subtract: Request.Subtract = undefined;
if (p.len < 4) return null;
subtract.x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
subtract.y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
subtract.width = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
subtract.height = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .subtract = subtract });
},
else => return null,
}
}
};
/// wl_subcompositor: sub-surface compositing
///
/// The global interface exposing sub-surface compositing capabilities.
/// A wl_surface, that has sub-surfaces associated, is called the
/// parent surface. Sub-surfaces can be arbitrarily nested and create
/// a tree of sub-surfaces.
/// The root surface in a tree of sub-surfaces is the main
/// surface. The main surface cannot be a sub-surface, because
/// sub-surfaces must always have a parent.
/// A main surface with its sub-surfaces forms a (compound) window.
/// For window management purposes, this set of wl_surface objects is
/// to be considered as a single window, and it should also behave as
/// such.
/// The aim of sub-surfaces is to offload some of the compositing work
/// within a window from clients to the compositor. A prime example is
/// a video player with decorations and video in separate wl_surface
/// objects. This should allow the compositor to pass YUV video buffer
/// processing to dedicated overlay hardware when possible.
pub const Subcompositor = struct {
resource: wayland.server.Resource,
pub fn version(subcompositor: Subcompositor) u32 {
return subcompositor.resource.version();
}
pub fn data(subcompositor: Subcompositor, comptime T: type) ?*T {
return subcompositor.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
destroy: Destroy,
get_subsurface: GetSubsurface,
/// destroy: unbind from the subcompositor interface
///
/// Informs the server that the client will not be using this
/// protocol object anymore. This does not affect any other
/// objects, wl_subsurface objects included.
pub const Destroy = struct {
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = true;
};
/// get_subsurface: give a surface the role sub-surface
///
/// Create a sub-surface interface for the given surface, and
/// associate it with the given parent surface. This turns a
/// plain wl_surface into a sub-surface.
/// The to-be sub-surface must not already have another role, and it
/// must not have an existing wl_subsurface object. Otherwise a protocol
/// error is raised.
/// Adding sub-surfaces to a parent is a double-buffered operation on the
/// parent (see wl_surface.commit). The effect of adding a sub-surface
/// becomes visible on the next time the state of the parent surface is
/// applied.
/// This request modifies the behaviour of wl_surface.commit request on
/// the sub-surface, see the documentation on wl_subsurface interface.
pub const GetSubsurface = struct {
id: Subsurface,
surface: Surface,
parent: Surface,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
};
pub const Event = union(enum) {};
/// error
pub const Error = error{BadSurface} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.BadSurface,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.BadSurface => 0,
else => null,
};
}
pub const error_bad_surface_since_version = 1;
pub fn marshal(subcompositor: Subcompositor, event: Event) void {
switch (event) {}
}
pub fn unmarshal(subcompositor: Subcompositor, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Destroy.opcode => {
var destroy: Request.Destroy = undefined;
return @as(Request, .{ .destroy = destroy });
},
Request.GetSubsurface.opcode => {
var get_subsurface: Request.GetSubsurface = undefined;
return @as(Request, .{ .get_subsurface = get_subsurface });
},
else => return null,
}
}
};
/// wl_subsurface: sub-surface interface to a wl_surface
///
/// An additional interface to a wl_surface object, which has been
/// made a sub-surface. A sub-surface has one parent surface. A
/// sub-surface's size and position are not limited to that of the parent.
/// Particularly, a sub-surface is not automatically clipped to its
/// parent's area.
/// A sub-surface becomes mapped, when a non-NULL wl_buffer is applied
/// and the parent surface is mapped. The order of which one happens
/// first is irrelevant. A sub-surface is hidden if the parent becomes
/// hidden, or if a NULL wl_buffer is applied. These rules apply
/// recursively through the tree of surfaces.
/// The behaviour of a wl_surface.commit request on a sub-surface
/// depends on the sub-surface's mode. The possible modes are
/// synchronized and desynchronized, see methods
/// wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized
/// mode caches the wl_surface state to be applied when the parent's
/// state gets applied, and desynchronized mode applies the pending
/// wl_surface state directly. A sub-surface is initially in the
/// synchronized mode.
/// Sub-surfaces have also other kind of state, which is managed by
/// wl_subsurface requests, as opposed to wl_surface requests. This
/// state includes the sub-surface position relative to the parent
/// surface (wl_subsurface.set_position), and the stacking order of
/// the parent and its sub-surfaces (wl_subsurface.place_above and
/// .place_below). This state is applied when the parent surface's
/// wl_surface state is applied, regardless of the sub-surface's mode.
/// As the exception, set_sync and set_desync are effective immediately.
/// The main surface can be thought to be always in desynchronized mode,
/// since it does not have a parent in the sub-surfaces sense.
/// Even if a sub-surface is in desynchronized mode, it will behave as
/// in synchronized mode, if its parent surface behaves as in
/// synchronized mode. This rule is applied recursively throughout the
/// tree of surfaces. This means, that one can set a sub-surface into
/// synchronized mode, and then assume that all its child and grand-child
/// sub-surfaces are synchronized, too, without explicitly setting them.
/// If the wl_surface associated with the wl_subsurface is destroyed, the
/// wl_subsurface object becomes inert. Note, that destroying either object
/// takes effect immediately. If you need to synchronize the removal
/// of a sub-surface to the parent surface update, unmap the sub-surface
/// first by attaching a NULL wl_buffer, update parent, and then destroy
/// the sub-surface.
/// If the parent wl_surface object is destroyed, the sub-surface is
/// unmapped.
pub const Subsurface = struct {
resource: wayland.server.Resource,
pub fn version(subsurface: Subsurface) u32 {
return subsurface.resource.version();
}
pub fn data(subsurface: Subsurface, comptime T: type) ?*T {
return subsurface.resource.data(T);
}
pub const interface_version = 1;
pub const Request = union(enum) {
destroy: Destroy,
set_position: SetPosition,
place_above: PlaceAbove,
place_below: PlaceBelow,
set_sync: SetSync,
set_desync: SetDesync,
/// destroy: remove sub-surface interface
///
/// The sub-surface interface is removed from the wl_surface object
/// that was turned into a sub-surface with a
/// wl_subcompositor.get_subsurface request. The wl_surface's association
/// to the parent is deleted, and the wl_surface loses its role as
/// a sub-surface. The wl_surface is unmapped immediately.
pub const Destroy = struct {
pub const since_version = 1;
pub const opcode: u16 = 0;
pub const destructor = true;
};
/// set_position: reposition the sub-surface
///
/// This schedules a sub-surface position change.
/// The sub-surface will be moved so that its origin (top left
/// corner pixel) will be at the location x, y of the parent surface
/// coordinate system. The coordinates are not restricted to the parent
/// surface area. Negative values are allowed.
/// The scheduled coordinates will take effect whenever the state of the
/// parent surface is applied. When this happens depends on whether the
/// parent surface is in synchronized mode or not. See
/// wl_subsurface.set_sync and wl_subsurface.set_desync for details.
/// If more than one set_position request is invoked by the client before
/// the commit of the parent surface, the position of a new request always
/// replaces the scheduled position from any previous request.
/// The initial position is 0, 0.
pub const SetPosition = struct {
x: i32,
y: i32,
pub const since_version = 1;
pub const opcode: u16 = 1;
pub const destructor = false;
};
/// place_above: restack the sub-surface
///
/// This sub-surface is taken from the stack, and put back just
/// above the reference surface, changing the z-order of the sub-surfaces.
/// The reference surface must be one of the sibling surfaces, or the
/// parent surface. Using any other surface, including this sub-surface,
/// will cause a protocol error.
/// The z-order is double-buffered. Requests are handled in order and
/// applied immediately to a pending state. The final pending state is
/// copied to the active state the next time the state of the parent
/// surface is applied. When this happens depends on whether the parent
/// surface is in synchronized mode or not. See wl_subsurface.set_sync and
/// wl_subsurface.set_desync for details.
/// A new sub-surface is initially added as the top-most in the stack
/// of its siblings and parent.
pub const PlaceAbove = struct {
sibling: Surface,
pub const since_version = 1;
pub const opcode: u16 = 2;
pub const destructor = false;
};
/// place_below: restack the sub-surface
///
/// The sub-surface is placed just below the reference surface.
/// See wl_subsurface.place_above.
pub const PlaceBelow = struct {
sibling: Surface,
pub const since_version = 1;
pub const opcode: u16 = 3;
pub const destructor = false;
};
/// set_sync: set sub-surface to synchronized mode
///
/// Change the commit behaviour of the sub-surface to synchronized
/// mode, also described as the parent dependent mode.
/// In synchronized mode, wl_surface.commit on a sub-surface will
/// accumulate the committed state in a cache, but the state will
/// not be applied and hence will not change the compositor output.
/// The cached state is applied to the sub-surface immediately after
/// the parent surface's state is applied. This ensures atomic
/// updates of the parent and all its synchronized sub-surfaces.
/// Applying the cached state will invalidate the cache, so further
/// parent surface commits do not (re-)apply old state.
/// See wl_subsurface for the recursive effect of this mode.
pub const SetSync = struct {
pub const since_version = 1;
pub const opcode: u16 = 4;
pub const destructor = false;
};
/// set_desync: set sub-surface to desynchronized mode
///
/// Change the commit behaviour of the sub-surface to desynchronized
/// mode, also described as independent or freely running mode.
/// In desynchronized mode, wl_surface.commit on a sub-surface will
/// apply the pending state directly, without caching, as happens
/// normally with a wl_surface. Calling wl_surface.commit on the
/// parent surface has no effect on the sub-surface's wl_surface
/// state. This mode allows a sub-surface to be updated on its own.
/// If cached state exists when wl_surface.commit is called in
/// desynchronized mode, the pending state is added to the cached
/// state, and applied as a whole. This invalidates the cache.
/// Note: even if a sub-surface is set to desynchronized, a parent
/// sub-surface may override it to behave as synchronized. For details,
/// see wl_subsurface.
/// If a surface's parent surface behaves as desynchronized, then
/// the cached state is applied on set_desync.
pub const SetDesync = struct {
pub const since_version = 1;
pub const opcode: u16 = 5;
pub const destructor = false;
};
};
pub const Event = union(enum) {};
/// error
pub const Error = error{BadSurface} || Display.Error;
pub fn errorFromInt(i: u32) ?Error {
return switch (i) {
0 => Error.BadSurface,
else => null,
};
}
pub fn errorToInt(e: Error) ?u32 {
return switch (i) {
Error.BadSurface => 0,
else => null,
};
}
pub const error_bad_surface_since_version = 1;
pub fn marshal(subsurface: Subsurface, event: Event) void {
switch (event) {}
}
pub fn unmarshal(subsurface: Subsurface, opcode: u16, message: []const u8) ?Request {
var p = message;
switch (opcode) {
Request.Destroy.opcode => {
var destroy: Request.Destroy = undefined;
return @as(Request, .{ .destroy = destroy });
},
Request.SetPosition.opcode => {
var set_position: Request.SetPosition = undefined;
if (p.len < 4) return null;
set_position.x = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
if (p.len < 4) return null;
set_position.y = @import("std").mem.bytesAsSlice(i32, p)[0];
p = p[@sizeOf(i32)..];
return @as(Request, .{ .set_position = set_position });
},
Request.PlaceAbove.opcode => {
var place_above: Request.PlaceAbove = undefined;
return @as(Request, .{ .place_above = place_above });
},
Request.PlaceBelow.opcode => {
var place_below: Request.PlaceBelow = undefined;
return @as(Request, .{ .place_below = place_below });
},
Request.SetSync.opcode => {
var set_sync: Request.SetSync = undefined;
return @as(Request, .{ .set_sync = set_sync });
},
Request.SetDesync.opcode => {
var set_desync: Request.SetDesync = undefined;
return @as(Request, .{ .set_desync = set_desync });
},
else => return null,
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment