#+build linux #+vet explicit-allocators package wayland import intr "base:intrinsics" import "core:bytes" import "core:fmt" import "core:io" import "core:log" import "core:strings" import "core:sys/linux" _message_read :: proc(session: ^Session) -> (message: Raw_Message, error: Error) { header := _unmarshal_raw(session.socket_stream, Message_Header) or_return buf := &session.message_read_buffer bytes.buffer_reset(buf) resize(&buf.buf, header.size - size_of(header)) payload := bytes.buffer_to_bytes(buf) io.read(session.socket_stream, payload) or_return return {header, payload}, nil } _msg_write :: proc(session: ^Session, object_id: $I/Object_ID, opcode: $O, args: ..Message_Primitive) -> Error where intr.type_core_type(O) == Opcode { buf := &session.message_write_buffer bytes.buffer_reset(buf) payload_stream := bytes.buffer_to_stream(buf) for arg in args { _marshal_primitive(payload_stream, arg) or_return } header := Message_Header{ object_id = Object_ID(object_id), opcode = Opcode(opcode), size = u16(size_of(Message_Header) + bytes.buffer_length(buf)), } _marshal_raw(session.socket_stream, header) or_return io.write(session.socket_stream, bytes.buffer_to_bytes(buf)) or_return _message_log(session, .Request, Object_ID(object_id), opcode, ..args) return nil } _Message_Log_Type :: enum { Request, Event } _message_log :: proc(session: ^Session, type: _Message_Log_Type, object_id: Object_ID, opcode: $O, arguments: ..Message_Primitive) { if !session.debug_logging_enabled { return } builder := &session.debug_log_builder strings.builder_reset(builder) if type == .Request { strings.write_string(builder, " -> ") } fmt.sbprintf(builder, "{}#{}.{}(", _get_object_interface_name(session, object_id), object_id, opcode) num_args := len(arguments) for argument, i in arguments { switch value in argument { case i32: strings.write_int(builder, int(value)) case u32: strings.write_uint(builder, uint(value)) case Object_ID: fmt.sbprintf(builder, "{}#{}", _get_object_interface_name(session, value), value) case Fixed: _string_builder_write_fixed(builder, value) case string: fmt.sbprintf(builder, "\"{}\"", value) case []byte: unimplemented() case linux.Fd: fmt.sbprintf(builder, "FD({})", value) } if i < num_args - 1 { strings.write_string(builder, ", ") } } strings.write_byte(builder, ')') log.debug(strings.to_string(builder^)) }