diff --git a/internal/pipewire/client.go b/internal/pipewire/client.go index 4480dc8..ce2b627 100644 --- a/internal/pipewire/client.go +++ b/internal/pipewire/client.go @@ -35,6 +35,26 @@ const ( PW_VERSION_CLIENT_METHODS = 0 ) +// The ClientInfo event provides client information updates. +// This is emitted when binding to a client or when the client info is updated later. +type ClientInfo struct { + // The global id of the client. + ID Int + // The changes emitted by this event. + ChangeMask Long + // Properties of this object, valid when change_mask has PW_CLIENT_CHANGE_MASK_PROPS. + Props *SPADict +} + +// MarshalBinary satisfies [encoding.BinaryMarshaler] via [Marshal]. +func (c *ClientInfo) MarshalBinary() ([]byte, error) { return Marshal(c) } + +// UnmarshalBinary satisfies [encoding.BinaryUnmarshaler] via [Unmarshal]. +func (c *ClientInfo) UnmarshalBinary(data []byte) error { + _, err := Unmarshal(data, c) + return err +} + // ClientUpdateProperties is used to update the properties of a client. type ClientUpdateProperties struct { // Props are properties to update on the client. diff --git a/internal/pipewire/client_test.go b/internal/pipewire/client_test.go index 378112b..c9d790c 100644 --- a/internal/pipewire/client_test.go +++ b/internal/pipewire/client_test.go @@ -6,6 +6,27 @@ import ( "hakurei.app/internal/pipewire" ) +func TestClientInfo(t *testing.T) { + t.Parallel() + + encodingTestCases[pipewire.ClientInfo, *pipewire.ClientInfo]{ + {"sample", []byte(recvmsg00Message02POD), pipewire.ClientInfo{ + ID: 34, + ChangeMask: pipewire.PW_CLIENT_CHANGE_MASK_PROPS, + Props: &pipewire.SPADict{NItems: 9, Items: []pipewire.SPADictItem{ + {Key: "pipewire.protocol", Value: "protocol-native"}, + {Key: "core.name", Value: "pipewire-0"}, + {Key: "pipewire.sec.socket", Value: "pipewire-0-manager"}, + {Key: "pipewire.sec.pid", Value: "1443"}, + {Key: "pipewire.sec.uid", Value: "1000"}, + {Key: "pipewire.sec.gid", Value: "100"}, + {Key: "module.id", Value: "2"}, + {Key: "object.id", Value: "34"}, + {Key: "object.serial", Value: "34"}, + }}}, nil}, + }.run(t) +} + func TestClientUpdateProperties(t *testing.T) { t.Parallel() diff --git a/internal/pipewire/header_test.go b/internal/pipewire/header_test.go index 5ac5910..0618988 100644 --- a/internal/pipewire/header_test.go +++ b/internal/pipewire/header_test.go @@ -47,6 +47,12 @@ func TestHeader(t *testing.T) { Size: 0x198, Sequence: 1, FileCount: 0, }, nil}, + {"PW_CLIENT_EVENT_INFO", []byte(recvmsg00Message02Header), pipewire.Header{ + ID: pipewire.PW_ID_CLIENT, + Opcode: pipewire.PW_CLIENT_EVENT_INFO, + Size: 0x1f0, Sequence: 2, FileCount: 0, + }, nil}, + {"PW_SECURITY_CONTEXT_METHOD_CREATE", []byte{ // Id 3, 0, 0, 0, diff --git a/internal/pipewire/pipewire_test.go b/internal/pipewire/pipewire_test.go index cd19001..9511e2f 100644 --- a/internal/pipewire/pipewire_test.go +++ b/internal/pipewire/pipewire_test.go @@ -36,4 +36,9 @@ var ( recvmsg00Message01Header string //go:embed testdata/12-recvmsg00-message01-POD recvmsg00Message01POD string + + //go:embed testdata/13-recvmsg00-message02-header + recvmsg00Message02Header string + //go:embed testdata/14-recvmsg00-message02-POD + recvmsg00Message02POD string ) diff --git a/internal/pipewire/testdata/13-recvmsg00-message02-header b/internal/pipewire/testdata/13-recvmsg00-message02-header new file mode 100644 index 0000000..d83c686 Binary files /dev/null and b/internal/pipewire/testdata/13-recvmsg00-message02-header differ diff --git a/internal/pipewire/testdata/14-recvmsg00-message02-POD b/internal/pipewire/testdata/14-recvmsg00-message02-POD new file mode 100644 index 0000000..8bb8ebb Binary files /dev/null and b/internal/pipewire/testdata/14-recvmsg00-message02-POD differ