#+build linux package wayland import "base:intrinsics" import "core:fmt" import "core:io" import "core:sys/linux" _marshal_raw :: proc(stream: io.Stream, value: $T) -> io.Error where T == u32 || T == i32 || T == Message_Header { data := transmute([size_of(T)]byte) value io.write(stream, data[:]) or_return return nil } _marshal_string :: proc(stream: io.Stream, value: string) -> io.Error { length := len(value) + 1 // +1 for null terminator _marshal_raw(stream, u32(length)) or_return io.write(stream, transmute([]byte) value) or_return io.write(stream, {0}) or_return // null terminator _marshal_padding(stream, length) or_return return nil } _marshal_fixed :: proc(stream: io.Stream, value: Fixed) -> io.Error { return _marshal_raw(stream, value.i) } _marshal_primitive :: proc(stream: io.Stream, primitive: Message_Primitive) -> io.Error { switch value in primitive { case u32: return _marshal_raw(stream, value) case i32: return _marshal_raw(stream, value) case Object_ID: return _marshal_raw(stream, u32(value)) case Fixed: return _marshal_fixed(stream, value) case string: return _marshal_string(stream, value) case []byte, linux.Fd: unimplemented(fmt.aprint(primitive)) } panic(fmt.aprint("Invalid union variant passed to _marshal_primitive:", primitive)) } // This is simply moving the cursor forward by remainder bytes - there really ought to be an io.discard() for streams... _marshal_padding :: proc(stream: io.Stream, written_length: int) -> io.Error { @(static, rodata) padding_buf: [4]byte remainder := (4 - (written_length % 4)) % 4 io.write(stream, padding_buf[:remainder]) or_return return nil }