aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pipewire
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-12-14 08:10:57 +0900
committerOphestra <cat@gensokyo.uk>2025-12-14 08:10:57 +0900
commita27dfdc058caf4ca0578a7cf98282c1998c94e6b (patch)
tree912506237d6cd9eb6b5c4fa6c74b4a3893b20a9e /internal/pipewire
parent6d0d9cecd11bee0b79bbd95cb989a356134e4b6c (diff)
internal/pipewire: implement Core::CreateObject
Nothing uses this right now, this would have to be called by wrapper methods on Registry that would search the objects Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pipewire')
-rw-r--r--internal/pipewire/core.go52
-rw-r--r--internal/pipewire/core_test.go56
2 files changed, 107 insertions, 1 deletions
diff --git a/internal/pipewire/core.go b/internal/pipewire/core.go
index 80bd217f..6adcac1d 100644
--- a/internal/pipewire/core.go
+++ b/internal/pipewire/core.go
@@ -572,6 +572,58 @@ func (ctx *Context) GetRegistry() (*Registry, error) {
)
}
+// CoreCreateObject is sent when the client requests to create a
+// new object from a factory of a certain type.
+//
+// The client allocates a new_id for the proxy. The server will
+// allocate a new resource with the same new_id and from then on,
+// Methods and Events will be exchanged between the new object of
+// the given type.
+type CoreCreateObject struct {
+ // The name of a server factory object to use.
+ FactoryName String `json:"factory_name"`
+ // The type of the object to create, this is also the type of
+ // the interface of the new_id proxy.
+ Type String `json:"type"`
+ // Undocumented, assumed to be the local version of the proxy.
+ Version Int `json:"version"`
+ // Extra properties to create the object.
+ Properties *SPADict `json:"props"`
+ // The proxy id of the new object.
+ NewID Int `json:"new_id"`
+}
+
+// Opcode satisfies [Message] with a constant value.
+func (c *CoreCreateObject) Opcode() byte { return PW_CORE_METHOD_CREATE_OBJECT }
+
+// FileCount satisfies [Message] with a constant value.
+func (c *CoreCreateObject) FileCount() Int { return 0 }
+
+// Size satisfies [KnownSize] with a value computed at runtime.
+func (c *CoreCreateObject) Size() Word {
+ return SizePrefix +
+ SizeString[Word](c.FactoryName) +
+ SizeString[Word](c.Type) +
+ Size(SizeInt) +
+ c.Properties.Size() +
+ Size(SizeInt)
+}
+
+// MarshalBinary satisfies [encoding.BinaryMarshaler] via [Marshal].
+func (c *CoreCreateObject) MarshalBinary() ([]byte, error) { return Marshal(c) }
+
+// UnmarshalBinary satisfies [encoding.BinaryUnmarshaler] via [Unmarshal].
+func (c *CoreCreateObject) UnmarshalBinary(data []byte) error { return Unmarshal(data, c) }
+
+// createObject queues a [CoreCreateObject] message for the PipeWire server.
+// This is not safe to use directly, callers should use typed wrapper methods on [Registry] instead.
+func (core *Core) createObject(factoryName, typeName String, version Int, props SPADict, newId Int) error {
+ return core.ctx.writeMessage(
+ PW_ID_CORE,
+ &CoreCreateObject{factoryName, typeName, version, &props, newId},
+ )
+}
+
// A RegistryGlobal event is emitted to notify a client about a new global object.
type RegistryGlobal struct {
// The global id.
diff --git a/internal/pipewire/core_test.go b/internal/pipewire/core_test.go
index 6d73b5c4..7785a74f 100644
--- a/internal/pipewire/core_test.go
+++ b/internal/pipewire/core_test.go
@@ -171,7 +171,7 @@ func TestCoreError(t *testing.T) {
/* padding */ 0, 0, 0, 0,
/* size: 0x1b bytes */ 0x1b, 0, 0, 0,
- /*type: String */ 8, 0, 0, 0,
+ /* type: String */ 8, 0, 0, 0,
// value: "no permission to destroy 0\x00"
0x6e, 0x6f, 0x20, 0x70,
@@ -306,6 +306,60 @@ func TestCoreGetRegistry(t *testing.T) {
}.run(t)
}
+func TestCoreCreateObject(t *testing.T) {
+ t.Parallel()
+
+ encodingTestCases[pipewire.CoreCreateObject, *pipewire.CoreCreateObject]{
+ {"sample", []byte{
+ /* size: rest of data */ 0x70, 0, 0, 0,
+ /* type: Struct */ 0xe, 0, 0, 0,
+
+ /* size: 0x13 bytes */ 0x13, 0, 0, 0,
+ /* type: String */ 8, 0, 0, 0,
+
+ // value: "spa-device-factory\x00"
+ 0x73, 0x70, 0x61, 0x2d,
+ 0x64, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x2d, 0x66,
+ 0x61, 0x63, 0x74, 0x6f,
+ 0x72, 0x79, 0, 0,
+ 0, 0, 0, 0,
+
+ /* size: 0x1a bytes */ 0x1a, 0, 0, 0,
+ /* type: String */ 8, 0, 0, 0,
+
+ // value: "PipeWire:Interface:Device\x00"
+ 0x50, 0x69, 0x70, 0x65,
+ 0x57, 0x69, 0x72, 0x65,
+ 0x3a, 0x49, 0x6e, 0x74,
+ 0x65, 0x72, 0x66, 0x61,
+ 0x63, 0x65, 0x3a, 0x44,
+ 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0, 0, 0,
+ 0, 0, 0, 0,
+
+ /* size: 4 bytes */ 4, 0, 0, 0,
+ /* type: Int */ 4, 0, 0, 0,
+ /* value: 3 */ 3, 0, 0, 0,
+ /* padding */ 0, 0, 0, 0,
+
+ /* size */ 0, 0, 0, 0,
+ /* type: None */ 1, 0, 0, 0,
+
+ /* size: 4 bytes */ 4, 0, 0, 0,
+ /* type: Int */ 4, 0, 0, 0,
+ /* value: 0xbad */ 0xad, 0xb, 0, 0,
+ /* padding */ 0, 0, 0, 0,
+ }, pipewire.CoreCreateObject{
+ FactoryName: "spa-device-factory",
+ Type: pipewire.PW_TYPE_INTERFACE_Device,
+ Version: pipewire.PW_VERSION_FACTORY,
+ Properties: new(pipewire.SPADict),
+ NewID: 0xbad,
+ }, nil},
+ }.run(t)
+}
+
func TestRegistryGlobal(t *testing.T) {
t.Parallel()