From 1acba78234e427054692d4e65653593036d8b744 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 13 Jul 2017 15:21:52 +0200 Subject: [PATCH] API cleanups Fix docs Add some more versions to interfaces Make types for the various proxy object + inline methods that does type checking and create proxys etc. Set owner client of client-nodes in the properties Pass type to bind to in create-node Don't place global id in the info structs Improve registration of marshal functions Pass more types around as ids --- doc/Doxyfile.in | 2 +- spa/include/spa/clock.h | 3 +- spa/include/spa/defs.h | 1 + spa/include/spa/log.h | 3 +- spa/include/spa/loop.h | 6 +- spa/include/spa/monitor.h | 9 +- spa/include/spa/node.h | 5 +- spa/include/spa/plugin.h | 6 +- spa/include/spa/type-map.h | 3 +- src/extensions/client-node.h | 116 ++++++-- src/gst/gstpipewiredeviceprovider.c | 61 ++-- src/gst/gstpipewiredeviceprovider.h | 2 +- src/gst/gstpipewiresrc.c | 3 - src/modules/module-autolink.c | 14 +- src/modules/module-client-node.c | 19 +- src/modules/module-client-node/client-node.c | 53 ++-- .../module-client-node/protocol-native.c | 143 +++++---- src/modules/module-flatpak.c | 34 ++- src/modules/module-protocol-native.c | 8 +- .../module-protocol-native/connection.c | 4 +- .../module-protocol-native/protocol-native.c | 279 ++++++++---------- src/modules/spa/module-node-factory.c | 7 +- src/pipewire/client.c | 22 +- src/pipewire/core.c | 157 ++++++---- src/pipewire/core.h | 28 +- src/pipewire/interfaces.h | 213 +++++++++++-- src/pipewire/introspect.c | 5 - src/pipewire/introspect.h | 5 - src/pipewire/link.c | 20 +- src/pipewire/module.c | 20 +- src/pipewire/node-factory.h | 5 +- src/pipewire/node.c | 20 +- src/pipewire/node.h | 6 +- src/pipewire/protocol.c | 52 ++-- src/pipewire/protocol.h | 29 +- src/pipewire/proxy.c | 26 +- src/pipewire/proxy.h | 46 +-- src/pipewire/remote.c | 23 +- src/pipewire/remote.h | 4 +- src/pipewire/resource.c | 22 +- src/pipewire/resource.h | 35 +-- src/pipewire/stream.c | 66 ++--- src/pipewire/type.c | 14 +- src/pipewire/type.h | 24 +- src/tools/pipewire-monitor.c | 104 ++++--- 45 files changed, 963 insertions(+), 764 deletions(-) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index ca0072a7f..53038f7a5 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -780,7 +780,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = "@top_srcdir@/src/" +INPUT = "@top_srcdir@/src/pipewire" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/spa/include/spa/clock.h b/spa/include/spa/clock.h index d296fcbea..d0f3fb84c 100644 --- a/spa/include/spa/clock.h +++ b/spa/include/spa/clock.h @@ -43,8 +43,6 @@ enum spa_clock_state { #include #include -#define SPA_VERSION_CLOCK 0 - /** * spa_clock: * @@ -53,6 +51,7 @@ enum spa_clock_state { struct spa_clock { /* the version of this clock. This can be used to expand this * structure in the future */ +#define SPA_VERSION_CLOCK 0 uint32_t version; const struct spa_dict *info; diff --git a/spa/include/spa/defs.h b/spa/include/spa/defs.h index fe32ecf40..6616914c6 100644 --- a/spa/include/spa/defs.h +++ b/spa/include/spa/defs.h @@ -70,6 +70,7 @@ enum spa_result { SPA_RESULT_SKIPPED = -34, SPA_RESULT_OUT_OF_BUFFERS = -35, SPA_RESULT_INCOMPATIBLE_PROPS = -36, + SPA_RESULT_INCOMPATIBLE_VERSION = -37, }; #define SPA_ASYNC_BIT (1 << 30) diff --git a/spa/include/spa/log.h b/spa/include/spa/log.h index 590c9faad..cb13b4bd9 100644 --- a/spa/include/spa/log.h +++ b/spa/include/spa/log.h @@ -42,8 +42,6 @@ enum spa_log_level { SPA_LOG_LEVEL_TRACE, }; -#define SPA_VERSION_LOG 0 - /** * struct spa_log: * @@ -52,6 +50,7 @@ enum spa_log_level { struct spa_log { /* the version of this log. This can be used to expand this * structure in the future */ +#define SPA_VERSION_LOG 0 uint32_t version; /** * struct spa_log::info diff --git a/spa/include/spa/loop.h b/spa/include/spa/loop.h index 8a0fd4de1..18e719648 100644 --- a/spa/include/spa/loop.h +++ b/spa/include/spa/loop.h @@ -66,8 +66,6 @@ typedef int (*spa_invoke_func_t) (struct spa_loop *loop, void *data, void *user_data); -#define SPA_VERSION_LOOP 0 - /** * spa_loop: * @@ -76,6 +74,7 @@ typedef int (*spa_invoke_func_t) (struct spa_loop *loop, struct spa_loop { /* the version of this structure. This can be used to expand this * structure in the future */ +#define SPA_VERSION_LOOP 0 uint32_t version; int (*add_source) (struct spa_loop *loop, @@ -160,8 +159,6 @@ typedef void (*spa_source_signal_func_t) (struct spa_loop_utils *utils, struct spa_source *source, int signal_number, void *data); -#define SPA_VERSION_LOOP_UTILS 0 - /** * struct spa_loop_utils: * @@ -170,6 +167,7 @@ typedef void (*spa_source_signal_func_t) (struct spa_loop_utils *utils, struct spa_loop_utils { /* the version of this structure. This can be used to expand this * structure in the future */ +#define SPA_VERSION_LOOP_UTILS 0 uint32_t version; struct spa_source *(*add_io) (struct spa_loop_utils *utils, diff --git a/spa/include/spa/monitor.h b/spa/include/spa/monitor.h index 7fb56a7a0..9f4a47550 100644 --- a/spa/include/spa/monitor.h +++ b/spa/include/spa/monitor.h @@ -104,19 +104,17 @@ enum spa_monitor_item_state { SPA_MONITOR_ITEM_STATE_UNAVAILABLE, }; -#define SPA_VERSION_MONITOR_CALLBACKS 0 - /** * spa_monitor_callbacks: */ struct spa_monitor_callbacks { - uint32_t version; /**< version of the structure */ + /** version of the structure */ +#define SPA_VERSION_MONITOR_CALLBACKS 0 + uint32_t version; void (*event) (struct spa_monitor *monitor, struct spa_event *event, void *user_data); }; -#define SPA_VERSION_MONITOR 0 - /** * spa_monitor: * @@ -125,6 +123,7 @@ struct spa_monitor_callbacks { struct spa_monitor { /* the version of this monitor. This can be used to expand this * structure in the future */ +#define SPA_VERSION_MONITOR 0 uint32_t version; /** diff --git a/spa/include/spa/node.h b/spa/include/spa/node.h index a7fc24106..553afb2d4 100644 --- a/spa/include/spa/node.h +++ b/spa/include/spa/node.h @@ -78,9 +78,9 @@ struct spa_port_info { const struct spa_dict *props; /**< extra port properties */ }; -#define SPA_VERSION_NODE_CALLBACKS 0 struct spa_node_callbacks { +#define SPA_VERSION_NODE_CALLBACKS 0 uint32_t version; /**< version of this structure */ /** Emited when an async operation completed */ @@ -134,8 +134,6 @@ struct spa_node_callbacks { }; -#define SPA_VERSION_NODE 0 - /** * struct spa_node: * @@ -147,6 +145,7 @@ struct spa_node_callbacks { struct spa_node { /* the version of this node. This can be used to expand this * structure in the future */ +#define SPA_VERSION_NODE 0 uint32_t version; /** * spa_node::info diff --git a/spa/include/spa/plugin.h b/spa/include/spa/plugin.h index cd9732a7b..71472dd3d 100644 --- a/spa/include/spa/plugin.h +++ b/spa/include/spa/plugin.h @@ -30,10 +30,9 @@ extern "C" { #define SPA_TYPE__Handle SPA_TYPE_INTERFACE_BASE "Handle" #define SPA_TYPE__HandleFactory SPA_TYPE_INTERFACE_BASE "HandleFactory" -#define SPA_VERSION_HANDLE 0 - struct spa_handle { /** Version of this struct */ +#define SPA_VERSION_HANDLE 0 uint32_t version; /* user_data that can be set by the application */ @@ -103,10 +102,9 @@ static inline void *spa_support_find(const struct spa_support *support, #define SPA_SUPPORT_INIT(type,data) (struct spa_support) { (type), (data) } -#define SPA_VERSION_HANDLE_FACTORY 0 - struct spa_handle_factory { /** The version of this structure */ +#define SPA_VERSION_HANDLE_FACTORY 0 uint32_t version; /** * spa_handle_factory::name diff --git a/spa/include/spa/type-map.h b/spa/include/spa/type-map.h index 8ea9bbb12..f45e16a5f 100644 --- a/spa/include/spa/type-map.h +++ b/spa/include/spa/type-map.h @@ -30,8 +30,6 @@ extern "C" { #define SPA_TYPE__TypeMap SPA_TYPE_INTERFACE_BASE "TypeMap" -#define SPA_VERSION_TYPE_MAP 0 - /** * spa_type_map: * @@ -40,6 +38,7 @@ extern "C" { struct spa_type_map { /* the version of this structure. This can be used to expand this * structure in the future */ +#define SPA_VERSION_TYPE_MAP 0 uint32_t version; /** * spa_type_map::info diff --git a/src/extensions/client-node.h b/src/extensions/client-node.h index 869a06c7d..f52e417b5 100644 --- a/src/extensions/client-node.h +++ b/src/extensions/client-node.h @@ -30,8 +30,13 @@ extern "C" { #include #include -#define PW_TYPE__ClientNode PW_TYPE_NODE_BASE "Client" -#define PW_TYPE_CLIENT_NODE_BASE PW_TYPE__ClientNode ":" +#include + +struct pw_client_node_proxy { struct pw_proxy proxy; }; + +#define PW_TYPE_INTERFACE__ClientNode PW_TYPE_INTERFACE_BASE "ClientNode" + +#define PW_VERSION_CLIENT_NODE 0 /** information about a buffer */ struct pw_client_node_buffer { @@ -41,17 +46,18 @@ struct pw_client_node_buffer { struct spa_buffer *buffer; /**< buffer describing metadata and buffer memory */ }; -#define PW_VERSION_CLIENT_NODE 0 - -#define PW_CLIENT_NODE_METHOD_DONE 0 -#define PW_CLIENT_NODE_METHOD_UPDATE 1 -#define PW_CLIENT_NODE_METHOD_PORT_UPDATE 2 -#define PW_CLIENT_NODE_METHOD_EVENT 3 -#define PW_CLIENT_NODE_METHOD_DESTROY 4 -#define PW_CLIENT_NODE_METHOD_NUM 5 +#define PW_CLIENT_NODE_METHOD_DONE 0 +#define PW_CLIENT_NODE_METHOD_UPDATE 1 +#define PW_CLIENT_NODE_METHOD_PORT_UPDATE 2 +#define PW_CLIENT_NODE_METHOD_EVENT 3 +#define PW_CLIENT_NODE_METHOD_DESTROY 4 +#define PW_CLIENT_NODE_METHOD_NUM 5 /** \ref pw_client_node methods */ struct pw_client_node_methods { +#define PW_VERSION_CLIENT_NODE_METHODS 0 + uint32_t version; + /** Complete an async operation */ void (*done) (void *object, int seq, int res); @@ -113,11 +119,60 @@ struct pw_client_node_methods { void (*destroy) (void *object); }; -#define pw_client_node_do_done(p,...) pw_proxy_do(p,struct pw_client_node_methods,done,__VA_ARGS__) -#define pw_client_node_do_update(p,...) pw_proxy_do(p,struct pw_client_node_methods,update,__VA_ARGS__) -#define pw_client_node_do_port_update(p,...) pw_proxy_do(p,struct pw_client_node_methods,port_update,__VA_ARGS__) -#define pw_client_node_do_event(p,...) pw_proxy_do(p,struct pw_client_node_methods,event,__VA_ARGS__) -#define pw_client_node_do_destroy(p) pw_proxy_do_na(p,struct pw_client_node_methods,destroy) +static inline void +pw_client_node_proxy_done(struct pw_client_node_proxy *p, int seq, int res) +{ + pw_proxy_do(&p->proxy, struct pw_client_node_methods, done, seq, res); +} + +static inline void +pw_client_node_proxy_update(struct pw_client_node_proxy *p, + uint32_t change_mask, + uint32_t max_input_ports, + uint32_t max_output_ports, + const struct spa_props *props) +{ + pw_proxy_do(&p->proxy, struct pw_client_node_methods, update, change_mask, + max_input_ports, + max_output_ports, + props); +} + +static inline void +pw_client_node_proxy_port_update(struct pw_client_node_proxy *p, + enum spa_direction direction, + uint32_t port_id, + uint32_t change_mask, + uint32_t n_possible_formats, + const struct spa_format **possible_formats, + const struct spa_format *format, + uint32_t n_params, + const struct spa_param **params, + const struct spa_port_info *info) +{ + pw_proxy_do(&p->proxy, struct pw_client_node_methods, port_update, direction, + port_id, + change_mask, + n_possible_formats, + possible_formats, + format, + n_params, + params, + info); +} + +static inline void +pw_client_node_proxy_event(struct pw_client_node_proxy *p, struct spa_event *event) +{ + pw_proxy_do(&p->proxy, struct pw_client_node_methods, event, event); +} + +static inline void +pw_client_node_proxy_destroy(struct pw_client_node_proxy *p) +{ + pw_proxy_do_na(&p->proxy, struct pw_client_node_methods, destroy); +} + #define PW_CLIENT_NODE_EVENT_TRANSPORT 0 #define PW_CLIENT_NODE_EVENT_SET_PROPS 1 @@ -134,6 +189,8 @@ struct pw_client_node_methods { /** \ref pw_client_node events */ struct pw_client_node_events { +#define PW_VERSION_CLIENT_NODE_EVENTS 0 + uint32_t version; /** * Notify of a new transport area * @@ -280,17 +337,24 @@ struct pw_client_node_events { }; -#define pw_client_node_notify_transport(r,...) pw_resource_notify(r,struct pw_client_node_events,transport,__VA_ARGS__) -#define pw_client_node_notify_set_props(r,...) pw_resource_notify(r,struct pw_client_node_events,props,__VA_ARGS__) -#define pw_client_node_notify_event(r,...) pw_resource_notify(r,struct pw_client_node_events,event,__VA_ARGS__) -#define pw_client_node_notify_add_port(r,...) pw_resource_notify(r,struct pw_client_node_events,add_port,__VA_ARGS__) -#define pw_client_node_notify_remove_port(r,...) pw_resource_notify(r,struct pw_client_node_events,remove_port,__VA_ARGS__) -#define pw_client_node_notify_set_format(r,...) pw_resource_notify(r,struct pw_client_node_events,set_format,__VA_ARGS__) -#define pw_client_node_notify_set_param(r,...) pw_resource_notify(r,struct pw_client_node_events,set_param,__VA_ARGS__) -#define pw_client_node_notify_add_mem(r,...) pw_resource_notify(r,struct pw_client_node_events,add_mem,__VA_ARGS__) -#define pw_client_node_notify_use_buffers(r,...) pw_resource_notify(r,struct pw_client_node_events,use_buffers,__VA_ARGS__) -#define pw_client_node_notify_node_command(r,...) pw_resource_notify(r,struct pw_client_node_events,node_command,__VA_ARGS__) -#define pw_client_node_notify_port_command(r,...) pw_resource_notify(r,struct pw_client_node_events,port_command,__VA_ARGS__) +static inline void +pw_client_node_proxy_add_listener(struct pw_client_node_proxy *p, + void *object, const struct pw_client_node_events *events) +{ + pw_proxy_add_listener(&p->proxy, object, events); +} + +#define pw_client_node_resource_transport(r,...) pw_resource_notify(r,struct pw_client_node_events,transport,__VA_ARGS__) +#define pw_client_node_resource_set_props(r,...) pw_resource_notify(r,struct pw_client_node_events,props,__VA_ARGS__) +#define pw_client_node_resource_event(r,...) pw_resource_notify(r,struct pw_client_node_events,event,__VA_ARGS__) +#define pw_client_node_resource_add_port(r,...) pw_resource_notify(r,struct pw_client_node_events,add_port,__VA_ARGS__) +#define pw_client_node_resource_remove_port(r,...) pw_resource_notify(r,struct pw_client_node_events,remove_port,__VA_ARGS__) +#define pw_client_node_resource_set_format(r,...) pw_resource_notify(r,struct pw_client_node_events,set_format,__VA_ARGS__) +#define pw_client_node_resource_set_param(r,...) pw_resource_notify(r,struct pw_client_node_events,set_param,__VA_ARGS__) +#define pw_client_node_resource_add_mem(r,...) pw_resource_notify(r,struct pw_client_node_events,add_mem,__VA_ARGS__) +#define pw_client_node_resource_use_buffers(r,...) pw_resource_notify(r,struct pw_client_node_events,use_buffers,__VA_ARGS__) +#define pw_client_node_resource_node_command(r,...) pw_resource_notify(r,struct pw_client_node_events,node_command,__VA_ARGS__) +#define pw_client_node_resource_port_command(r,...) pw_resource_notify(r,struct pw_client_node_events,port_command,__VA_ARGS__) #ifdef __cplusplus } /* extern "C" */ diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index f833d798c..d9c8111c8 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -193,7 +193,7 @@ enum }; static GstDevice * -new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info) +new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info, uint32_t id) { GstCaps *caps = NULL; GstStructure *props; @@ -234,7 +234,7 @@ new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info) if (klass == NULL) klass = "unknown/unknown"; - return gst_pipewire_device_new (info->id, + return gst_pipewire_device_new (id, info->name, caps, klass, @@ -295,18 +295,24 @@ on_sync_reply (struct pw_listener *listener, struct pw_remote *remote, uint32_t { GstPipeWireDeviceProvider *self = SPA_CONTAINER_OF (listener, GstPipeWireDeviceProvider, on_sync_reply); if (seq == 1) - pw_core_do_sync(self->registry->remote->core_proxy, 2); + pw_core_proxy_sync(self->remote->core_proxy, 2); else if (seq == 2) self->end = true; } +struct node_data { + GstPipeWireDeviceProvider *self; + uint32_t id; +}; + static void node_event_info(void *object, struct pw_node_info *info) { struct pw_proxy *proxy = object; - GstPipeWireDeviceProvider *self = proxy->object; + struct node_data *node_data = proxy->user_data; + GstPipeWireDeviceProvider *self = node_data->self; GstDevice *dev; - dev = new_node (self, info); + dev = new_node (self, info, node_data->id); if (dev) { if(self->list_only) *self->devices = g_list_prepend (*self->devices, gst_object_ref_sink (dev)); @@ -316,26 +322,32 @@ static void node_event_info(void *object, struct pw_node_info *info) } static const struct pw_node_events node_events = { + PW_VERSION_NODE_EVENTS, &node_event_info }; + static void registry_event_global(void *object, uint32_t id, uint32_t type, uint32_t version) { - struct pw_proxy *registry = object; - GstPipeWireDeviceProvider *self = registry->object; - struct pw_remote *remote = registry->remote; + struct pw_registry_proxy *registry = object; + GstPipeWireDeviceProvider *self = registry->proxy.user_data; + struct pw_remote *remote = self->remote; struct pw_core *core = remote->core; - struct pw_proxy *proxy = NULL; + struct pw_node_proxy *node; + struct node_data *data; if (type != core->type.node) return; - proxy = pw_proxy_new(remote, SPA_ID_INVALID, core->type.node, 0); - if (proxy == NULL) + node = pw_registry_proxy_bind(registry, id, core->type.node, PW_VERSION_NODE, + sizeof(struct node_data), NULL); + if (node == NULL) goto no_mem; - pw_proxy_set_implementation(proxy, self, PW_VERSION_NODE, &node_events, NULL); - pw_registry_do_bind(registry, id, version, proxy->id); + data = node->proxy.user_data; + data->id = id; + data->self = self; + pw_node_proxy_add_listener(node, node, &node_events); return; no_mem: @@ -345,8 +357,8 @@ no_mem: static void registry_event_global_remove(void *object, uint32_t id) { - struct pw_proxy *registry = object; - GstPipeWireDeviceProvider *self = registry->object; + struct pw_registry_proxy *registry = object; + GstPipeWireDeviceProvider *self = registry->proxy.user_data; GstDeviceProvider *provider = GST_DEVICE_PROVIDER (self); GstPipeWireDevice *dev; @@ -358,6 +370,7 @@ static void registry_event_global_remove(void *object, uint32_t id) } static const struct pw_registry_events registry_events = { + PW_VERSION_REGISTRY_EVENTS, registry_event_global, registry_event_global_remove, }; @@ -369,7 +382,7 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider) struct pw_loop *l = NULL; struct pw_core *c = NULL; struct pw_remote *r = NULL; - struct pw_proxy *reg = NULL; + struct pw_registry_proxy *reg = NULL; GST_DEBUG_OBJECT (self, "starting probe"); @@ -410,10 +423,10 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider) self->list_only = TRUE; self->devices = NULL; - reg = pw_proxy_new(r, SPA_ID_INVALID, c->type.registry, 0); - pw_proxy_set_implementation(reg, self, PW_VERSION_REGISTRY, ®istry_events, NULL); - pw_core_do_get_registry(r->core_proxy, PW_VERSION_REGISTRY, reg->id); - pw_core_do_sync(r->core_proxy, 1); + reg = pw_core_proxy_get_registry(r->core_proxy, PW_VERSION_REGISTRY, 0, NULL); + reg->proxy.user_data = self; + pw_registry_proxy_add_listener(reg, reg, ®istry_events); + pw_core_proxy_sync(r->core_proxy, 1); for (;;) { if (r->state <= 0) @@ -515,10 +528,10 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider) GST_DEBUG_OBJECT (self, "connected"); get_core_info (self->remote, self); - self->registry = pw_proxy_new(self->remote, SPA_ID_INVALID, self->core->type.registry, 0); - pw_proxy_set_implementation(self->registry, self, PW_VERSION_REGISTRY, ®istry_events, NULL); - pw_core_do_get_registry(self->remote->core_proxy, PW_VERSION_REGISTRY, self->registry->id); - pw_core_do_sync(self->remote->core_proxy, 1); + self->registry = pw_core_proxy_get_registry(self->remote->core_proxy, PW_VERSION_REGISTRY, 0, NULL); + self->registry->proxy.user_data = self; + pw_registry_proxy_add_listener(self->registry, self->registry, ®istry_events); + pw_core_proxy_sync(self->remote->core_proxy, 1); pw_thread_loop_unlock (self->main_loop); diff --git a/src/gst/gstpipewiredeviceprovider.h b/src/gst/gstpipewiredeviceprovider.h index 462d98c3a..38633084d 100644 --- a/src/gst/gstpipewiredeviceprovider.h +++ b/src/gst/gstpipewiredeviceprovider.h @@ -86,7 +86,7 @@ struct _GstPipeWireDeviceProvider { struct pw_core *core; struct pw_remote *remote; - struct pw_proxy *registry; + struct pw_registry_proxy *registry; gboolean end; gboolean list_only; GList **devices; diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 482ff60bd..aef9a8da6 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -554,9 +554,6 @@ gst_pipewire_src_stream_start (GstPipeWireSrc *pwsrc) } parse_stream_properties (pwsrc, pwsrc->stream->properties); - pw_thread_loop_unlock (pwsrc->main_loop); - - pw_thread_loop_lock (pwsrc->main_loop); GST_DEBUG_OBJECT (pwsrc, "signal started"); pwsrc->started = TRUE; pw_thread_loop_signal (pwsrc->main_loop, FALSE); diff --git a/src/modules/module-autolink.c b/src/modules/module-autolink.c index edcb145bd..ea1234b80 100644 --- a/src/modules/module-autolink.c +++ b/src/modules/module-autolink.c @@ -101,13 +101,13 @@ on_link_state_changed(struct pw_listener *listener, link->error); spa_list_for_each(resource, &link->resource_list, link) { - pw_core_notify_error(resource->client->core_resource, - resource->id, SPA_RESULT_ERROR, link->error); + pw_core_resource_error(resource->client->core_resource, + resource->id, SPA_RESULT_ERROR, link->error); } if (info->node->owner) { - pw_core_notify_error(info->node->owner->client->core_resource, - info->node->owner->id, - SPA_RESULT_ERROR, link->error); + pw_core_resource_error(info->node->owner->client->core_resource, + info->node->owner->id, + SPA_RESULT_ERROR, link->error); } break; } @@ -194,8 +194,8 @@ static void try_link_port(struct pw_node *node, struct pw_port *port, struct nod error: pw_log_error("module %p: can't link node '%s'", impl, error); if (info->node->owner && info->node->owner->client->core_resource) { - pw_core_notify_error(info->node->owner->client->core_resource, - info->node->owner->id, SPA_RESULT_ERROR, error); + pw_core_resource_error(info->node->owner->client->core_resource, + info->node->owner->id, SPA_RESULT_ERROR, error); } free(error); return; diff --git a/src/modules/module-client-node.c b/src/modules/module-client-node.c index b0f887294..d780d2f51 100644 --- a/src/modules/module-client-node.c +++ b/src/modules/module-client-node.c @@ -44,6 +44,14 @@ static struct pw_node *create_node(struct pw_node_factory *factory, { struct pw_client_node *node; + if (properties == NULL) + properties = pw_properties_new(NULL, NULL); + if (properties == NULL) + goto no_mem; + + pw_properties_setf(properties, + "pipewire.owner.client", "%d", resource->client->global->id); + node = pw_client_node_new(resource, name, properties); if (node == NULL) goto no_mem; @@ -52,8 +60,10 @@ static struct pw_node *create_node(struct pw_node_factory *factory, no_mem: pw_log_error("can't create node"); - pw_core_notify_error(resource->client->core_resource, - resource->client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); + pw_core_resource_error(resource->client->core_resource, + resource->client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); + if (properties) + pw_properties_free(properties); return NULL; } @@ -68,7 +78,7 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope impl->this.core = core; impl->this.name = "client-node"; - impl->this.type = spa_type_map_get_id(core->type.map, PW_TYPE__ClientNode); + pw_signal_init(&impl->this.destroy_signal); impl->this.create_node = create_node; @@ -76,7 +86,8 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope spa_list_insert(core->node_factory_list.prev, &impl->this.link); - pw_core_add_global(core, NULL, core->type.node_factory, 0, impl, NULL, &impl->this.global); + pw_core_add_global(core, NULL, core->type.node_factory, 0, + NULL, impl, &impl->this.global); return impl; } diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 295826f17..8d6ca810d 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -114,8 +114,6 @@ struct proxy { struct impl { struct pw_client_node this; - uint32_t type_client_node; - struct pw_core *core; struct proxy proxy; @@ -194,10 +192,10 @@ static int spa_proxy_node_send_command(struct spa_node *node, struct spa_command core = this->impl->core; if (SPA_COMMAND_TYPE(command) == core->type.command_node.ClockUpdate) { - pw_client_node_notify_node_command(this->resource, this->seq++, command); + pw_client_node_resource_node_command(this->resource, this->seq++, command); } else { /* send start */ - pw_client_node_notify_node_command(this->resource, this->seq, command); + pw_client_node_resource_node_command(this->resource, this->seq, command); if (SPA_COMMAND_TYPE(command) == core->type.command_node.Start) send_need_input(this); @@ -470,8 +468,8 @@ spa_proxy_node_port_set_format(struct spa_node *node, if (this->resource == NULL) return SPA_RESULT_OK; - pw_client_node_notify_set_format(this->resource, - this->seq, direction, port_id, flags, format); + pw_client_node_resource_set_format(this->resource, + this->seq, direction, port_id, flags, format); return SPA_RESULT_RETURN_ASYNC(this->seq++); } @@ -644,12 +642,12 @@ spa_proxy_node_port_use_buffers(struct spa_node *node, mb[i].offset = 0; mb[i].size = msh->size; - pw_client_node_notify_add_mem(this->resource, - direction, - port_id, - mb[i].mem_id, - impl->core->type.data.MemFd, - msh->fd, msh->flags, msh->offset, msh->size); + pw_client_node_resource_add_mem(this->resource, + direction, + port_id, + mb[i].mem_id, + impl->core->type.data.MemFd, + msh->fd, msh->flags, msh->offset, msh->size); for (j = 0; j < buffers[i]->n_metas; j++) { memcpy(&b->buffer.metas[j], &buffers[i]->metas[j], sizeof(struct spa_meta)); @@ -662,13 +660,13 @@ spa_proxy_node_port_use_buffers(struct spa_node *node, if (d->type == impl->core->type.data.DmaBuf || d->type == impl->core->type.data.MemFd) { - pw_client_node_notify_add_mem(this->resource, - direction, - port_id, - n_mem, - d->type, - d->fd, - d->flags, d->mapoffset, d->maxsize); + pw_client_node_resource_add_mem(this->resource, + direction, + port_id, + n_mem, + d->type, + d->fd, + d->flags, d->mapoffset, d->maxsize); b->buffer.datas[j].type = impl->core->type.data.Id; b->buffer.datas[j].data = SPA_UINT32_TO_PTR(n_mem); n_mem++; @@ -683,8 +681,8 @@ spa_proxy_node_port_use_buffers(struct spa_node *node, } } - pw_client_node_notify_use_buffers(this->resource, - this->seq, direction, port_id, n_buffers, mb); + pw_client_node_resource_use_buffers(this->resource, + this->seq, direction, port_id, n_buffers, mb); return SPA_RESULT_RETURN_ASYNC(this->seq++); } @@ -948,6 +946,7 @@ static void client_node_destroy(void *object) } static struct pw_client_node_methods client_node_methods = { + PW_VERSION_CLIENT_NODE_METHODS, &client_node_done, &client_node_update, &client_node_port_update, @@ -1053,8 +1052,8 @@ static void on_initialized(struct pw_listener *listener, struct pw_node *node) pw_client_node_get_fds(this, &readfd, &writefd); pw_transport_get_info(impl->transport, &info); - pw_client_node_notify_transport(this->resource, node->global->id, - readfd, writefd, info.memfd, info.offset, info.size); + pw_client_node_resource_transport(this->resource, node->global->id, + readfd, writefd, info.memfd, info.offset, info.size); } static void @@ -1150,8 +1149,6 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource, impl->fds[0] = impl->fds[1] = -1; pw_log_debug("client-node %p: new", impl); - impl->type_client_node = spa_type_map_get_id(core->type.map, PW_TYPE__ClientNode); - pw_signal_init(&this->destroy_signal); proxy_init(&impl->proxy, NULL, core->support, core->n_support); @@ -1168,11 +1165,9 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource, if (this->node == NULL) goto error_no_node; + this->resource->destroy = (pw_destroy_t) client_node_resource_destroy; pw_resource_set_implementation(this->resource, - this, - PW_VERSION_CLIENT_NODE, - &client_node_methods, - (pw_destroy_t) client_node_resource_destroy); + this, &client_node_methods); impl->proxy.resource = this->resource; diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index 0c2bd03e6..d6eb28b20 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -158,7 +158,7 @@ static bool client_node_demarshal_set_props(void *object, void *data, size_t siz -SPA_POD_TYPE_OBJECT, &props, 0)) return false; - ((struct pw_client_node_events *) proxy->implementation)->set_props(proxy, seq, props); + pw_proxy_notify(proxy, struct pw_client_node_events, set_props, seq, props); return true; } @@ -173,7 +173,7 @@ static bool client_node_demarshal_event_event(void *object, void *data, size_t s !spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &event, 0)) return false; - ((struct pw_client_node_events *) proxy->implementation)->event(proxy, event); + pw_proxy_notify(proxy, struct pw_client_node_events, event, event); return true; } @@ -189,8 +189,7 @@ static bool client_node_demarshal_add_port(void *object, void *data, size_t size SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, 0)) return false; - ((struct pw_client_node_events *) proxy->implementation)->add_port(proxy, seq, direction, - port_id); + pw_proxy_notify(proxy, struct pw_client_node_events, add_port, seq, direction, port_id); return true; } @@ -206,8 +205,7 @@ static bool client_node_demarshal_remove_port(void *object, void *data, size_t s SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, 0)) return false; - ((struct pw_client_node_events *) proxy->implementation)->remove_port(proxy, seq, direction, - port_id); + pw_proxy_notify(proxy, struct pw_client_node_events, remove_port, seq, direction, port_id); return true; } @@ -228,9 +226,8 @@ static bool client_node_demarshal_set_format(void *object, void *data, size_t si -SPA_POD_TYPE_OBJECT, &format, 0)) return false; - ((struct pw_client_node_events *) proxy->implementation)->set_format(proxy, seq, direction, - port_id, flags, - format); + pw_proxy_notify(proxy, struct pw_client_node_events, set_format, seq, direction, port_id, + flags, format); return true; } @@ -250,8 +247,7 @@ static bool client_node_demarshal_set_param(void *object, void *data, size_t siz -SPA_POD_TYPE_OBJECT, ¶m, 0)) return false; - ((struct pw_client_node_events *) proxy->implementation)->set_param(proxy, seq, direction, - port_id, param); + pw_proxy_notify(proxy, struct pw_client_node_events, set_param, seq, direction, port_id, param); return true; } @@ -276,12 +272,11 @@ static bool client_node_demarshal_add_mem(void *object, void *data, size_t size) memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx); - ((struct pw_client_node_events *) proxy->implementation)->add_mem(proxy, - direction, - port_id, - mem_id, - type, - memfd, flags, offset, sz); + pw_proxy_notify(proxy, struct pw_client_node_events, add_mem, direction, + port_id, + mem_id, + type, + memfd, flags, offset, sz); return true; } @@ -340,11 +335,10 @@ static bool client_node_demarshal_use_buffers(void *object, void *data, size_t s d->data = SPA_UINT32_TO_PTR(data_id); } } - ((struct pw_client_node_events *) proxy->implementation)->use_buffers(proxy, - seq, - direction, - port_id, - n_buffers, buffers); + pw_proxy_notify(proxy, struct pw_client_node_events, use_buffers, seq, + direction, + port_id, + n_buffers, buffers); return true; } @@ -360,7 +354,7 @@ static bool client_node_demarshal_node_command(void *object, void *data, size_t !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &seq, SPA_POD_TYPE_OBJECT, &command, 0)) return false; - ((struct pw_client_node_events *) proxy->implementation)->node_command(proxy, seq, command); + pw_proxy_notify(proxy, struct pw_client_node_events, node_command, seq, command); return true; } @@ -379,10 +373,9 @@ static bool client_node_demarshal_port_command(void *object, void *data, size_t SPA_POD_TYPE_OBJECT, &command, 0)) return false; - ((struct pw_client_node_events *) proxy->implementation)->port_command(proxy, - direction, - port_id, - command); + pw_proxy_notify(proxy, struct pw_client_node_events, port_command, direction, + port_id, + command); return true; } @@ -409,9 +402,9 @@ static bool client_node_demarshal_transport(void *object, void *data, size_t siz if (readfd == -1 || writefd == -1 || memfd_idx == -1) return false; - ((struct pw_client_node_events *) proxy->implementation)->transport(proxy, node_id, - readfd, writefd, - memfd, offset, sz); + pw_proxy_notify(proxy, struct pw_client_node_events, transport, node_id, + readfd, writefd, + memfd, offset, sz); return true; } @@ -666,7 +659,7 @@ static bool client_node_demarshal_done(void *object, void *data, size_t size) SPA_POD_TYPE_INT, &res, 0)) return false; - ((struct pw_client_node_methods *) resource->implementation)->done(resource, seq, res); + pw_resource_do(resource, struct pw_client_node_methods, done, seq, res); return true; } @@ -685,10 +678,10 @@ static bool client_node_demarshal_update(void *object, void *data, size_t size) SPA_POD_TYPE_INT, &max_output_ports, -SPA_POD_TYPE_OBJECT, &props, 0)) return false; - ((struct pw_client_node_methods *) resource->implementation)->update(resource, change_mask, - max_input_ports, - max_output_ports, - props); + pw_resource_do(resource, struct pw_client_node_methods, update, change_mask, + max_input_ports, + max_output_ports, + props); return true; } @@ -738,15 +731,14 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s return false; } - ((struct pw_client_node_methods *) resource->implementation)->port_update(resource, - direction, - port_id, - change_mask, - n_possible_formats, - possible_formats, - format, - n_params, - params, infop); + pw_resource_do(resource, struct pw_client_node_methods, port_update, direction, + port_id, + change_mask, + n_possible_formats, + possible_formats, + format, + n_params, + params, infop); return true; } @@ -761,7 +753,7 @@ static bool client_node_demarshal_event_method(void *object, void *data, size_t !spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &event, 0)) return false; - ((struct pw_client_node_methods *) resource->implementation)->event(resource, event); + pw_resource_do(resource, struct pw_client_node_methods, event, event); return true; } @@ -773,11 +765,12 @@ static bool client_node_demarshal_destroy(void *object, void *data, size_t size) if (!spa_pod_iter_struct(&it, data, size)) return false; - ((struct pw_client_node_methods *) resource->implementation)->destroy(resource); + pw_resource_do_na(resource, struct pw_client_node_methods, destroy); return true; } -static const struct pw_client_node_methods pw_protocol_native_client_client_node_methods = { +static const struct pw_client_node_methods pw_protocol_native_client_node_method_marshal = { + PW_VERSION_CLIENT_NODE_METHODS, &client_node_marshal_done, &client_node_marshal_update, &client_node_marshal_port_update, @@ -785,28 +778,7 @@ static const struct pw_client_node_methods pw_protocol_native_client_client_node &client_node_marshal_destroy }; -static const demarshal_func_t pw_protocol_native_client_client_node_demarshal[] = { - &client_node_demarshal_transport, - &client_node_demarshal_set_props, - &client_node_demarshal_event_event, - &client_node_demarshal_add_port, - &client_node_demarshal_remove_port, - &client_node_demarshal_set_format, - &client_node_demarshal_set_param, - &client_node_demarshal_add_mem, - &client_node_demarshal_use_buffers, - &client_node_demarshal_node_command, - &client_node_demarshal_port_command, -}; - -static const struct pw_interface pw_protocol_native_client_client_node_interface = { - PW_TYPE__ClientNode, - PW_VERSION_CLIENT_NODE, - PW_CLIENT_NODE_METHOD_NUM, &pw_protocol_native_client_client_node_methods, - PW_CLIENT_NODE_EVENT_NUM, pw_protocol_native_client_client_node_demarshal, -}; - -static const demarshal_func_t pw_protocol_native_server_client_node_demarshal[] = { +static const demarshal_func_t pw_protocol_native_client_node_method_demarshal[] = { &client_node_demarshal_done, &client_node_demarshal_update, &client_node_demarshal_port_update, @@ -814,7 +786,8 @@ static const demarshal_func_t pw_protocol_native_server_client_node_demarshal[] &client_node_demarshal_destroy, }; -static const struct pw_client_node_events pw_protocol_native_server_client_node_events = { +static const struct pw_client_node_events pw_protocol_native_client_node_event_marshal = { + PW_VERSION_CLIENT_NODE_EVENTS, &client_node_marshal_transport, &client_node_marshal_set_props, &client_node_marshal_event_event, @@ -828,11 +801,29 @@ static const struct pw_client_node_events pw_protocol_native_server_client_node_ &client_node_marshal_port_command, }; -const struct pw_interface pw_protocol_native_server_client_node_interface = { - PW_TYPE__ClientNode, +static const demarshal_func_t pw_protocol_native_client_node_event_demarshal[] = { + &client_node_demarshal_transport, + &client_node_demarshal_set_props, + &client_node_demarshal_event_event, + &client_node_demarshal_add_port, + &client_node_demarshal_remove_port, + &client_node_demarshal_set_format, + &client_node_demarshal_set_param, + &client_node_demarshal_add_mem, + &client_node_demarshal_use_buffers, + &client_node_demarshal_node_command, + &client_node_demarshal_port_command, +}; + +const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = { + PW_TYPE_INTERFACE__ClientNode, PW_VERSION_CLIENT_NODE, - PW_CLIENT_NODE_METHOD_NUM, &pw_protocol_native_server_client_node_demarshal, - PW_CLIENT_NODE_EVENT_NUM, &pw_protocol_native_server_client_node_events, + PW_CLIENT_NODE_METHOD_NUM, + &pw_protocol_native_client_node_method_marshal, + &pw_protocol_native_client_node_method_demarshal, + PW_CLIENT_NODE_EVENT_NUM, + &pw_protocol_native_client_node_event_marshal, + pw_protocol_native_client_node_event_demarshal, }; struct pw_protocol *pw_protocol_native_ext_client_node_init(struct pw_core *core) @@ -844,9 +835,7 @@ struct pw_protocol *pw_protocol_native_ext_client_node_init(struct pw_core *core if (protocol == NULL) return NULL; - pw_protocol_add_interfaces(protocol, - &pw_protocol_native_client_client_node_interface, - &pw_protocol_native_server_client_node_interface); + pw_protocol_add_marshal(protocol, &pw_protocol_native_client_node_marshal); return protocol; } diff --git a/src/modules/module-flatpak.c b/src/modules/module-flatpak.c index 396bc58b1..297cad50e 100644 --- a/src/modules/module-flatpak.c +++ b/src/modules/module-flatpak.c @@ -69,8 +69,9 @@ struct async_pending { struct pw_resource *resource; char *factory_name; char *name; - struct pw_properties *properties; + uint32_t type; uint32_t version; + struct pw_properties *properties; uint32_t new_id; }; @@ -230,8 +231,9 @@ do_global_filter(struct pw_global *global, struct pw_client *client, void *data) if (link->input && !check_global_owner(client->core, client, link->input->node->global)) return false; - } else if (!check_global_owner(client->core, client, global)) - return false; + } + else if (!check_global_owner(client->core, client, global)) + return false; return true; } @@ -268,12 +270,13 @@ portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data) cinfo->old_methods->create_node (p->resource, p->factory_name, p->name, - &p->properties->dict, + p->type, p->version, + &p->properties->dict, p->new_id); } else { - pw_core_notify_error(cinfo->client->core_resource, - p->resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); + pw_core_resource_error(cinfo->client->core_resource, + p->resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); } free_pending(p); @@ -288,8 +291,9 @@ portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data) static void do_create_node(void *object, const char *factory_name, const char *name, - const struct spa_dict *props, + uint32_t type, uint32_t version, + const struct spa_dict *props, uint32_t new_id) { struct pw_resource *resource = object; @@ -306,7 +310,7 @@ static void do_create_node(void *object, struct async_pending *p; if (!cinfo->is_sandboxed) { - cinfo->old_methods->create_node (object, factory_name, name, props, version, new_id); + cinfo->old_methods->create_node (object, factory_name, name, type, version, props, new_id); return; } if (strcmp(factory_name, "client-node") != 0) { @@ -362,8 +366,9 @@ static void do_create_node(void *object, p->resource = resource; p->factory_name = strdup(factory_name); p->name = strdup(name); - p->properties = props ? pw_properties_new_dict(props) : NULL; + p->type = type; p->version = version; + p->properties = props ? pw_properties_new_dict(props) : NULL; p->new_id = new_id; pw_client_set_busy(client, true); @@ -393,8 +398,8 @@ static void do_create_node(void *object, dbus_error_free(&error); goto not_allowed; not_allowed: - pw_core_notify_error(client->core_resource, - resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); + pw_core_resource_error(client->core_resource, + resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); return; } @@ -413,8 +418,8 @@ do_create_link(void *object, struct pw_client *client = resource->client; if (cinfo->is_sandboxed) { - pw_core_notify_error(client->core_resource, - resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); + pw_core_resource_error(client->core_resource, + resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); return; } cinfo->old_methods->create_link (object, @@ -432,9 +437,8 @@ static void on_resource_impl(struct pw_listener *listener, struct pw_resource *resource) { struct client_info *cinfo = SPA_CONTAINER_OF(listener, struct client_info, resource_impl); - struct impl *impl = cinfo->impl; - if (resource->type == impl->core->type.core) { + if (resource->type == client->core->type.core) { cinfo->old_methods = resource->implementation; cinfo->core_methods = *cinfo->old_methods; resource->implementation = &cinfo->core_methods; diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index 3c59af2d2..a36a67eaf 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -116,13 +116,13 @@ process_messages(struct pw_client *client) client->protocol, id); continue; } - if (opcode >= resource->iface->n_methods) { + if (opcode >= resource->marshal->n_methods) { pw_log_error("protocol-native %p: invalid method %u %u", client->protocol, id, opcode); pw_client_destroy(client); break; } - demarshal = resource->iface->methods; + demarshal = resource->marshal->method_demarshal; if (!demarshal[opcode] || !demarshal[opcode] (resource, message, size)) { pw_log_error("protocol-native %p: invalid message received %u %u", client->protocol, id, opcode); @@ -449,13 +449,13 @@ on_remote_data(struct spa_loop_utils *utils, pw_log_error("protocol-native %p: could not find proxy %u", this, id); continue; } - if (opcode >= proxy->iface->n_events) { + if (opcode >= proxy->marshal->n_events) { pw_log_error("protocol-native %p: invalid method %u for %u", this, opcode, id); continue; } - demarshal = proxy->iface->events; + demarshal = proxy->marshal->event_demarshal; if (demarshal[opcode]) { if (!demarshal[opcode] (proxy, message, size)) pw_log_error diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c index cbd257e4e..1959f2c0c 100644 --- a/src/modules/module-protocol-native/connection.c +++ b/src/modules/module-protocol-native/connection.c @@ -375,7 +375,7 @@ pw_protocol_native_connection_begin_resource(struct pw_protocol_native_connectio types[i] = spa_type_map_get_type(core->type.map, b); client->n_types += diff; - pw_core_notify_update_types(client->core_resource, base, diff, types); + pw_core_resource_update_types(client->core_resource, base, diff, types); } impl->dest_id = resource->id; @@ -404,7 +404,7 @@ pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection * types[i] = spa_type_map_get_type(core->type.map, b); remote->n_types += diff; - pw_core_do_update_types(remote->core_proxy, base, diff, types); + pw_core_proxy_update_types(remote->core_proxy, base, diff, types); } impl->dest_id = proxy->id; diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index a4467c88c..c0ada9ce9 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -89,9 +89,9 @@ static void core_marshal_get_registry(void *object, uint32_t version, uint32_t n static void core_marshal_create_node(void *object, - const char *factory_name, - const char *name, const struct spa_dict *props, - uint32_t version, uint32_t new_id) + const char *factory_name, const char *name, + uint32_t type, uint32_t version, + const struct spa_dict *props, uint32_t new_id) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -105,7 +105,10 @@ core_marshal_create_node(void *object, spa_pod_builder_add(b, SPA_POD_TYPE_STRUCT, &f, SPA_POD_TYPE_STRING, factory_name, - SPA_POD_TYPE_STRING, name, SPA_POD_TYPE_INT, n_items, 0); + SPA_POD_TYPE_STRING, name, + SPA_POD_TYPE_ID, type, + SPA_POD_TYPE_INT, version, + SPA_POD_TYPE_INT, n_items, 0); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, @@ -113,7 +116,6 @@ core_marshal_create_node(void *object, SPA_POD_TYPE_STRING, props->items[i].value, 0); } spa_pod_builder_add(b, - SPA_POD_TYPE_INT, version, SPA_POD_TYPE_INT, new_id, -SPA_POD_TYPE_STRUCT, &f, 0); @@ -192,7 +194,6 @@ static bool core_demarshal_info(void *object, void *data, size_t size) if (!spa_pod_iter_struct(&it, data, size) || !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, SPA_POD_TYPE_LONG, &info.change_mask, SPA_POD_TYPE_STRING, &info.user_name, SPA_POD_TYPE_STRING, &info.host_name, @@ -292,7 +293,6 @@ static void core_marshal_info(void *object, struct pw_core_info *info) spa_pod_builder_add(b, SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, SPA_POD_TYPE_LONG, info->change_mask, SPA_POD_TYPE_STRING, info->user_name, SPA_POD_TYPE_STRING, info->host_name, @@ -437,14 +437,18 @@ static bool core_demarshal_create_node(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_iter it; - uint32_t version, new_id, i; + uint32_t version, type, new_id, i; const char *factory_name, *name; struct spa_dict props; if (!spa_pod_iter_struct(&it, data, size) || + !pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &resource->client->types) || !spa_pod_iter_get(&it, SPA_POD_TYPE_STRING, &factory_name, - SPA_POD_TYPE_STRING, &name, SPA_POD_TYPE_INT, &props.n_items, 0)) + SPA_POD_TYPE_STRING, &name, + SPA_POD_TYPE_ID, &type, + SPA_POD_TYPE_INT, &version, + SPA_POD_TYPE_INT, &props.n_items, 0)) return false; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); @@ -455,12 +459,12 @@ static bool core_demarshal_create_node(void *object, void *data, size_t size) return false; } if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &version, SPA_POD_TYPE_INT, &new_id, 0)) return false; - pw_resource_do(resource, struct pw_core_methods, create_node, factory_name, - name, &props, version, new_id); + pw_resource_do(resource, struct pw_core_methods, create_node, factory_name, name, + type, version, + &props, new_id); return true; } @@ -558,16 +562,18 @@ static bool registry_demarshal_bind(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_iter it; - uint32_t id, version, new_id; + uint32_t id, version, type, new_id; if (!spa_pod_iter_struct(&it, data, size) || + !pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &resource->client->types) || !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &id, + SPA_POD_TYPE_ID, &type, SPA_POD_TYPE_INT, &version, SPA_POD_TYPE_INT, &new_id, 0)) return false; - pw_resource_do(resource, struct pw_registry_methods, bind, id, version, new_id); + pw_resource_do(resource, struct pw_registry_methods, bind, id, type, version, new_id); return true; } @@ -584,7 +590,6 @@ static void module_marshal_info(void *object, struct pw_module_info *info) spa_pod_builder_add(b, SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, SPA_POD_TYPE_LONG, info->change_mask, SPA_POD_TYPE_STRING, info->name, SPA_POD_TYPE_STRING, info->filename, @@ -610,7 +615,6 @@ static bool module_demarshal_info(void *object, void *data, size_t size) if (!spa_pod_iter_struct(&it, data, size) || !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, SPA_POD_TYPE_LONG, &info.change_mask, SPA_POD_TYPE_STRING, &info.name, SPA_POD_TYPE_STRING, &info.filename, @@ -640,7 +644,6 @@ static void node_marshal_info(void *object, struct pw_node_info *info) spa_pod_builder_add(b, SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, SPA_POD_TYPE_LONG, info->change_mask, SPA_POD_TYPE_STRING, info->name, SPA_POD_TYPE_INT, info->max_input_ports, @@ -685,7 +688,6 @@ static bool node_demarshal_info(void *object, void *data, size_t size) if (!spa_pod_iter_struct(&it, data, size) || !pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &proxy->remote->types) || !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, SPA_POD_TYPE_LONG, &info.change_mask, SPA_POD_TYPE_STRING, &info.name, SPA_POD_TYPE_INT, &info.max_input_ports, @@ -740,7 +742,6 @@ static void client_marshal_info(void *object, struct pw_client_info *info) spa_pod_builder_add(b, SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, SPA_POD_TYPE_LONG, info->change_mask, SPA_POD_TYPE_INT, n_items, 0); for (i = 0; i < n_items; i++) { @@ -763,7 +764,6 @@ static bool client_demarshal_info(void *object, void *data, size_t size) if (!spa_pod_iter_struct(&it, data, size) || !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, SPA_POD_TYPE_LONG, &info.change_mask, SPA_POD_TYPE_INT, &props.n_items, 0)) return false; @@ -789,7 +789,6 @@ static void link_marshal_info(void *object, struct pw_link_info *info) b = pw_protocol_native_begin_resource(resource, PW_LINK_EVENT_INFO); spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, info->id, SPA_POD_TYPE_LONG, info->change_mask, SPA_POD_TYPE_INT, info->output_node_id, SPA_POD_TYPE_INT, info->output_port_id, @@ -809,7 +808,6 @@ static bool link_demarshal_info(void *object, void *data, size_t size) if (!spa_pod_iter_struct(&it, data, size) || !pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &proxy->remote->types) || !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, SPA_POD_TYPE_LONG, &info.change_mask, SPA_POD_TYPE_INT, &info.output_node_id, SPA_POD_TYPE_INT, &info.output_port_id, @@ -854,7 +852,8 @@ static bool registry_demarshal_global_remove(void *object, void *data, size_t si return true; } -static void registry_marshal_bind(void *object, uint32_t id, uint32_t version, uint32_t new_id) +static void registry_marshal_bind(void *object, uint32_t id, + uint32_t type, uint32_t version, uint32_t new_id) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -864,13 +863,15 @@ static void registry_marshal_bind(void *object, uint32_t id, uint32_t version, u spa_pod_builder_struct(b, &f, SPA_POD_TYPE_INT, id, + SPA_POD_TYPE_ID, type, SPA_POD_TYPE_INT, version, SPA_POD_TYPE_INT, new_id); pw_protocol_native_end_proxy(proxy, b); } -static const struct pw_core_methods pw_protocol_native_client_core_methods = { +static const struct pw_core_methods pw_protocol_native_core_method_marshal = { + PW_VERSION_CORE_METHODS, &core_marshal_update_types_client, &core_marshal_sync, &core_marshal_get_registry, @@ -879,82 +880,7 @@ static const struct pw_core_methods pw_protocol_native_client_core_methods = { &core_marshal_create_link }; -static const demarshal_func_t pw_protocol_native_client_core_demarshal[PW_CORE_EVENT_NUM] = { - &core_demarshal_update_types_client, - &core_demarshal_done, - &core_demarshal_error, - &core_demarshal_remove_id, - &core_demarshal_info -}; - -static const struct pw_interface pw_protocol_native_client_core_interface = { - PW_TYPE__Core, - PW_VERSION_CORE, - PW_CORE_METHOD_NUM, &pw_protocol_native_client_core_methods, - PW_CORE_EVENT_NUM, pw_protocol_native_client_core_demarshal -}; - -static const struct pw_registry_methods pw_protocol_native_client_registry_methods = { - ®istry_marshal_bind -}; - -static const demarshal_func_t pw_protocol_native_client_registry_demarshal[] = { - ®istry_demarshal_global, - ®istry_demarshal_global_remove, -}; - -static const struct pw_interface pw_protocol_native_client_registry_interface = { - PW_TYPE__Registry, - PW_VERSION_REGISTRY, - PW_REGISTRY_METHOD_NUM, &pw_protocol_native_client_registry_methods, - PW_REGISTRY_EVENT_NUM, pw_protocol_native_client_registry_demarshal, -}; - -static const demarshal_func_t pw_protocol_native_client_module_demarshal[] = { - &module_demarshal_info, -}; - -static const struct pw_interface pw_protocol_native_client_module_interface = { - PW_TYPE__Module, - PW_VERSION_MODULE, - 0, NULL, - PW_MODULE_EVENT_NUM, pw_protocol_native_client_module_demarshal, -}; - -static const demarshal_func_t pw_protocol_native_client_node_demarshal[] = { - &node_demarshal_info, -}; - -static const struct pw_interface pw_protocol_native_client_node_interface = { - PW_TYPE__Node, - PW_VERSION_NODE, - 0, NULL, - PW_NODE_EVENT_NUM, pw_protocol_native_client_node_demarshal, -}; - -static const demarshal_func_t pw_protocol_native_client_client_demarshal[] = { - &client_demarshal_info, -}; - -static const struct pw_interface pw_protocol_native_client_client_interface = { - PW_TYPE__Client, - PW_VERSION_CLIENT, - 0, NULL, - PW_CLIENT_EVENT_NUM, pw_protocol_native_client_client_demarshal, -}; - -static const demarshal_func_t pw_protocol_native_client_link_demarshal[] = { - &link_demarshal_info, -}; - -static const struct pw_interface pw_protocol_native_client_link_interface = { - PW_TYPE__Link, - PW_VERSION_LINK, - 0, NULL, - PW_LINK_EVENT_NUM, pw_protocol_native_client_link_demarshal, -}; - -static const demarshal_func_t pw_protocol_native_server_core_demarshal[PW_CORE_METHOD_NUM] = { +static const demarshal_func_t pw_protocol_native_core_method_demarshal[PW_CORE_METHOD_NUM] = { &core_demarshal_update_types_server, &core_demarshal_sync, &core_demarshal_get_registry, @@ -963,7 +889,8 @@ static const demarshal_func_t pw_protocol_native_server_core_demarshal[PW_CORE_M &core_demarshal_create_link }; -static const struct pw_core_events pw_protocol_native_server_core_events = { +static const struct pw_core_events pw_protocol_native_core_event_marshal = { + PW_VERSION_CORE_EVENTS, &core_marshal_update_types_server, &core_marshal_done, &core_marshal_error, @@ -971,92 +898,134 @@ static const struct pw_core_events pw_protocol_native_server_core_events = { &core_marshal_info }; -const struct pw_interface pw_protocol_native_server_core_interface = { - PW_TYPE__Core, - PW_VERSION_CORE, - PW_CORE_METHOD_NUM, pw_protocol_native_server_core_demarshal, - PW_CORE_EVENT_NUM, &pw_protocol_native_server_core_events, +static const demarshal_func_t pw_protocol_native_core_event_demarshal[PW_CORE_EVENT_NUM] = { + &core_demarshal_update_types_client, + &core_demarshal_done, + &core_demarshal_error, + &core_demarshal_remove_id, + &core_demarshal_info }; -static const demarshal_func_t pw_protocol_native_server_registry_demarshal[] = { +static const struct pw_protocol_marshal pw_protocol_native_core_marshal = { + PW_TYPE_INTERFACE__Core, + PW_VERSION_CORE, + PW_CORE_METHOD_NUM, + &pw_protocol_native_core_method_marshal, + pw_protocol_native_core_method_demarshal, + PW_CORE_EVENT_NUM, + &pw_protocol_native_core_event_marshal, + pw_protocol_native_core_event_demarshal +}; + +static const struct pw_registry_methods pw_protocol_native_registry_method_marshal = { + PW_VERSION_REGISTRY_METHODS, + ®istry_marshal_bind +}; + +static const demarshal_func_t pw_protocol_native_registry_method_demarshal[] = { ®istry_demarshal_bind, }; -static const struct pw_registry_events pw_protocol_native_server_registry_events = { +static const struct pw_registry_events pw_protocol_native_registry_event_marshal = { + PW_VERSION_REGISTRY_EVENTS, ®istry_marshal_global, ®istry_marshal_global_remove, }; -const struct pw_interface pw_protocol_native_server_registry_interface = { - PW_TYPE__Registry, - PW_VERSION_REGISTRY, - PW_REGISTRY_METHOD_NUM, pw_protocol_native_server_registry_demarshal, - PW_REGISTRY_EVENT_NUM, &pw_protocol_native_server_registry_events, +static const demarshal_func_t pw_protocol_native_registry_event_demarshal[] = { + ®istry_demarshal_global, + ®istry_demarshal_global_remove, }; -static const struct pw_module_events pw_protocol_native_server_module_events = { +const struct pw_protocol_marshal pw_protocol_native_registry_marshal = { + PW_TYPE_INTERFACE__Registry, + PW_VERSION_REGISTRY, + PW_REGISTRY_METHOD_NUM, + &pw_protocol_native_registry_method_marshal, + pw_protocol_native_registry_method_demarshal, + PW_REGISTRY_EVENT_NUM, + &pw_protocol_native_registry_event_marshal, + pw_protocol_native_registry_event_demarshal, +}; + +static const struct pw_module_events pw_protocol_native_module_event_marshal = { + PW_VERSION_MODULE_EVENTS, &module_marshal_info, }; -const struct pw_interface pw_protocol_native_server_module_interface = { - PW_TYPE__Module, - PW_VERSION_MODULE, - 0, NULL, - PW_MODULE_EVENT_NUM, &pw_protocol_native_server_module_events, +static const demarshal_func_t pw_protocol_native_module_event_demarshal[] = { + &module_demarshal_info, }; -static const struct pw_node_events pw_protocol_native_server_node_events = { +const struct pw_protocol_marshal pw_protocol_native_module_marshal = { + PW_TYPE_INTERFACE__Module, + PW_VERSION_MODULE, + 0, NULL, NULL, + PW_MODULE_EVENT_NUM, + &pw_protocol_native_module_event_marshal, + pw_protocol_native_module_event_demarshal, +}; + +static const struct pw_node_events pw_protocol_native_node_event_marshal = { + PW_VERSION_NODE_EVENTS, &node_marshal_info, }; -const struct pw_interface pw_protocol_native_server_node_interface = { - PW_TYPE__Node, - PW_VERSION_NODE, - 0, NULL, - PW_NODE_EVENT_NUM, &pw_protocol_native_server_node_events, +static const demarshal_func_t pw_protocol_native_node_event_demarshal[] = { + &node_demarshal_info, }; -static const struct pw_client_events pw_protocol_native_server_client_events = { +static const struct pw_protocol_marshal pw_protocol_native_node_marshal = { + PW_TYPE_INTERFACE__Node, + PW_VERSION_NODE, + 0, NULL, NULL, + PW_NODE_EVENT_NUM, + &pw_protocol_native_node_event_marshal, + pw_protocol_native_node_event_demarshal, +}; + +static const struct pw_client_events pw_protocol_native_client_event_marshal = { + PW_VERSION_CLIENT_EVENTS, &client_marshal_info, }; -const struct pw_interface pw_protocol_native_server_client_interface = { - PW_TYPE__Client, - PW_VERSION_CLIENT, - 0, NULL, - PW_CLIENT_EVENT_NUM, &pw_protocol_native_server_client_events, +static const demarshal_func_t pw_protocol_native_client_event_demarshal[] = { + &client_demarshal_info, }; -static const struct pw_link_events pw_protocol_native_server_link_events = { +static const struct pw_protocol_marshal pw_protocol_native_client_marshal = { + PW_TYPE_INTERFACE__Client, + PW_VERSION_CLIENT, + 0, NULL, NULL, + PW_CLIENT_EVENT_NUM, + &pw_protocol_native_client_event_marshal, + pw_protocol_native_client_event_demarshal, +}; + +static const struct pw_link_events pw_protocol_native_link_event_marshal = { + PW_VERSION_LINK_EVENTS, &link_marshal_info, }; -const struct pw_interface pw_protocol_native_server_link_interface = { - PW_TYPE__Link, +static const demarshal_func_t pw_protocol_native_link_event_demarshal[] = { + &link_demarshal_info, +}; + +static const struct pw_protocol_marshal pw_protocol_native_link_marshal = { + PW_TYPE_INTERFACE__Link, PW_VERSION_LINK, - 0, NULL, - PW_LINK_EVENT_NUM, &pw_protocol_native_server_link_events, + 0, NULL, NULL, + PW_LINK_EVENT_NUM, + &pw_protocol_native_link_event_marshal, + pw_protocol_native_link_event_demarshal, }; void pw_protocol_native_init(struct pw_protocol *protocol) { - pw_protocol_add_interfaces(protocol, - &pw_protocol_native_client_core_interface, - &pw_protocol_native_server_core_interface); - pw_protocol_add_interfaces(protocol, - &pw_protocol_native_client_registry_interface, - &pw_protocol_native_server_registry_interface); - pw_protocol_add_interfaces(protocol, - &pw_protocol_native_client_module_interface, - &pw_protocol_native_server_module_interface); - pw_protocol_add_interfaces(protocol, - &pw_protocol_native_client_node_interface, - &pw_protocol_native_server_node_interface); - pw_protocol_add_interfaces(protocol, - &pw_protocol_native_client_client_interface, - &pw_protocol_native_server_client_interface); - pw_protocol_add_interfaces(protocol, - &pw_protocol_native_client_link_interface, - &pw_protocol_native_server_link_interface); - + pw_protocol_add_marshal(protocol, &pw_protocol_native_core_marshal); + pw_protocol_add_marshal(protocol, &pw_protocol_native_registry_marshal); + pw_protocol_add_marshal(protocol, &pw_protocol_native_module_marshal); + pw_protocol_add_marshal(protocol, &pw_protocol_native_node_marshal); + pw_protocol_add_marshal(protocol, &pw_protocol_native_client_marshal); + pw_protocol_add_marshal(protocol, &pw_protocol_native_link_marshal); } diff --git a/src/modules/spa/module-node-factory.c b/src/modules/spa/module-node-factory.c index 29a50f2b0..6b6718f29 100644 --- a/src/modules/spa/module-node-factory.c +++ b/src/modules/spa/module-node-factory.c @@ -66,7 +66,7 @@ static struct pw_node *create_node(struct pw_node_factory *factory, no_properties: pw_log_error("missing properties"); if (resource) { - pw_core_notify_error(resource->client->core_resource, + pw_core_resource_error(resource->client->core_resource, resource->client->core_resource->id, SPA_RESULT_INVALID_ARGUMENTS, "missing properties"); } @@ -74,7 +74,7 @@ static struct pw_node *create_node(struct pw_node_factory *factory, no_mem: pw_log_error("can't create node"); if (resource) { - pw_core_notify_error(resource->client->core_resource, + pw_core_resource_error(resource->client->core_resource, resource->client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); } @@ -97,7 +97,8 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope spa_list_insert(core->node_factory_list.prev, &impl->this.link); - pw_core_add_global(core, NULL, core->type.node_factory, 0, impl, NULL, &impl->this.global); + pw_core_add_global(core, NULL, core->type.node_factory, 0, + NULL, impl, &impl->this.global); return impl; } diff --git a/src/pipewire/client.c b/src/pipewire/client.c index 52e603f97..a2734ba6e 100644 --- a/src/pipewire/client.c +++ b/src/pipewire/client.c @@ -38,30 +38,33 @@ static void client_unbind_func(void *data) } static int -client_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id) +client_bind_func(struct pw_global *global, + struct pw_client *client, + uint32_t version, uint32_t id) { struct pw_client *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, version, 0); + resource = pw_resource_new(client, id, global->type, version, 0, client_unbind_func); if (resource == NULL) goto no_mem; - pw_resource_set_implementation(resource, global->object, PW_VERSION_CLIENT, NULL, client_unbind_func); + pw_resource_set_implementation(resource, this, NULL); - pw_log_debug("client %p: bound to %d", global->object, resource->id); + pw_log_debug("client %p: bound to %d", this, resource->id); spa_list_insert(this->resource_list.prev, &resource->link); this->info.change_mask = ~0; - pw_client_notify_info(resource, &this->info); + pw_client_resource_info(resource, &this->info); + this->info.change_mask = 0; return SPA_RESULT_OK; no_mem: pw_log_error("can't create client resource"); - pw_core_notify_error(client->core_resource, - client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); + pw_core_resource_error(client->core_resource, + client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); return SPA_RESULT_NO_MEMORY; } @@ -111,9 +114,8 @@ struct pw_client *pw_client_new(struct pw_core *core, spa_list_insert(core->client_list.prev, &this->link); pw_core_add_global(core, NULL, core->type.client, PW_VERSION_CLIENT, - this, client_bind_func, &this->global); + client_bind_func, this, &this->global); - this->info.id = this->global->id; this->info.props = this->properties ? &this->properties->dict : NULL; return this; @@ -192,7 +194,7 @@ void pw_client_update_properties(struct pw_client *client, const struct spa_dict pw_signal_emit(&client->properties_changed, client); spa_list_for_each(resource, &client->resource_list, link) { - pw_client_notify_info(resource, &client->info); + pw_client_resource_info(resource, &client->info); } } diff --git a/src/pipewire/core.c b/src/pipewire/core.c index 63e588d47..c5dc15812 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -32,7 +32,6 @@ /** \cond */ struct global_impl { struct pw_global this; - pw_bind_func_t bind; }; struct impl { @@ -53,39 +52,59 @@ static bool pw_global_is_visible(struct pw_global *global, core->global_filter(global, client, core->global_filter_data)); } -static void registry_bind(void *object, uint32_t id, uint32_t version, uint32_t new_id) +static struct pw_global *find_global(struct pw_core *core, uint32_t id) +{ + struct pw_global *global; + spa_list_for_each(global, &core->global_list, link) { + if (global->id == id) + return global; + } + return NULL; +} + +static void registry_bind(void *object, uint32_t id, + uint32_t type, uint32_t version, uint32_t new_id) { struct pw_resource *resource = object; struct pw_client *client = resource->client; struct pw_core *core = resource->core; struct pw_global *global; + const char *type_name; - spa_list_for_each(global, &core->global_list, link) { - if (global->id == id) - break; - } - if (&global->link == &core->global_list) + if ((global = find_global(core, id)) == 0) goto no_id; if (!pw_global_is_visible(global, client)) - goto no_id; + goto no_id; + + if (type != global->type) + goto wrong_interface; + + type_name = spa_type_map_get_type(core->type.map, type); + + pw_log_debug("global %p: bind global id %d, iface %s to %d", global, id, type_name, new_id); - pw_log_debug("global %p: bind object id %d to %d", global, id, new_id); pw_global_bind(global, client, version, new_id); return; no_id: pw_log_debug("registry %p: no global with id %u to bind to %u", resource, id, new_id); + goto exit; + wrong_interface: + pw_log_debug("registry %p: global with id %u has no interface %u", resource, id, type); + goto exit; + exit: /* unmark the new_id the map, the client does not yet know about the failed * bind and will choose the next id, which we would refuse when we don't mark * new_id as 'used and freed' */ pw_map_insert_at(&client->objects, new_id, NULL); - pw_core_notify_remove_id(client->core_resource, new_id); + pw_core_resource_remove_id(client->core_resource, new_id); return; } static struct pw_registry_methods registry_methods = { + PW_VERSION_REGISTRY_METHODS, ®istry_bind }; @@ -106,7 +125,7 @@ static void core_sync(void *object, uint32_t seq) { struct pw_resource *resource = object; - pw_core_notify_done(resource, seq); + pw_core_resource_done(resource, seq); } static void core_get_registry(void *object, uint32_t version, uint32_t new_id) @@ -121,40 +140,40 @@ static void core_get_registry(void *object, uint32_t version, uint32_t new_id) new_id, this->type.registry, version, - 0); + 0, destroy_registry_resource); if (registry_resource == NULL) goto no_mem; pw_resource_set_implementation(registry_resource, - this, - PW_VERSION_REGISTRY, - ®istry_methods, - destroy_registry_resource); + registry_resource, + ®istry_methods); spa_list_insert(this->registry_resource_list.prev, ®istry_resource->link); spa_list_for_each(global, &this->global_list, link) { - if (pw_global_is_visible(global, client)) - pw_registry_notify_global(registry_resource, - global->id, - global->type, - global->version); + if (pw_global_is_visible(global, client)) { + pw_registry_resource_global(registry_resource, + global->id, + global->type, + global->version); + } } return; no_mem: pw_log_error("can't create registry resource"); - pw_core_notify_error(client->core_resource, - resource->id, SPA_RESULT_NO_MEMORY, "no memory"); + pw_core_resource_error(client->core_resource, + resource->id, SPA_RESULT_NO_MEMORY, "no memory"); } static void core_create_node(void *object, const char *factory_name, const char *name, - const struct spa_dict *props, + uint32_t type, uint32_t version, + const struct spa_dict *props, uint32_t new_id) { struct pw_resource *resource = object; @@ -167,11 +186,7 @@ core_create_node(void *object, if (factory == NULL) goto no_factory; - node_resource = pw_resource_new(client, - new_id, - factory->type, - version, - 0); + node_resource = pw_resource_new(client, new_id, type, version, 0, NULL); if (node_resource == NULL) goto no_resource; @@ -191,8 +206,8 @@ core_create_node(void *object, no_factory: pw_log_error("can't find node factory"); - pw_core_notify_error(client->core_resource, - resource->id, SPA_RESULT_INVALID_ARGUMENTS, "unknown factory name"); + pw_core_resource_error(client->core_resource, + resource->id, SPA_RESULT_INVALID_ARGUMENTS, "unknown factory name"); goto done; no_resource: @@ -203,8 +218,8 @@ core_create_node(void *object, pw_resource_destroy(node_resource); goto no_mem; no_mem: - pw_core_notify_error(client->core_resource, - resource->id, SPA_RESULT_NO_MEMORY, "no memory"); + pw_core_resource_error(client->core_resource, + resource->id, SPA_RESULT_NO_MEMORY, "no memory"); goto done; } @@ -222,8 +237,8 @@ core_create_link(void *object, struct pw_client *client = resource->client; pw_log_error("can't create link"); - pw_core_notify_error(client->core_resource, - resource->id, SPA_RESULT_NOT_IMPLEMENTED, "not implemented"); + pw_core_resource_error(client->core_resource, + resource->id, SPA_RESULT_NOT_IMPLEMENTED, "not implemented"); } static void core_update_types(void *object, uint32_t first_id, uint32_t n_types, const char **types) @@ -241,6 +256,7 @@ static void core_update_types(void *object, uint32_t first_id, uint32_t n_types, } static const struct pw_core_methods core_methods = { + PW_VERSION_CORE_METHODS, &core_update_types, &core_sync, &core_get_registry, @@ -257,26 +273,27 @@ static void core_unbind_func(void *data) } static int -core_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id) +core_bind_func(struct pw_global *global, + struct pw_client *client, + uint32_t version, + uint32_t id) { struct pw_core *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, version, 0); + resource = pw_resource_new(client, id, global->type, version, 0, core_unbind_func); if (resource == NULL) goto no_mem; - pw_resource_set_implementation(resource, global->object, - PW_VERSION_CORE, &core_methods, core_unbind_func); + pw_resource_set_implementation(resource, resource, &core_methods); spa_list_insert(this->resource_list.prev, &resource->link); client->core_resource = resource; - pw_log_debug("core %p: bound to %d", global->object, resource->id); + pw_log_debug("core %p: bound to %d", this, resource->id); this->info.change_mask = PW_CORE_CHANGE_MASK_ALL; - pw_core_notify_info(resource, &this->info); - this->info.change_mask = 0; + pw_core_resource_info(resource, &this->info); return SPA_RESULT_OK; @@ -343,9 +360,8 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro pw_signal_init(&this->global_removed); pw_core_add_global(this, NULL, this->type.core, PW_VERSION_CORE, - this, core_bind_func, &this->global); + core_bind_func, this, &this->global); - this->info.id = this->global->id; this->info.change_mask = 0; this->info.user_name = pw_get_user_name(); this->info.host_name = pw_get_host_name(); @@ -397,7 +413,8 @@ void pw_core_destroy(struct pw_core *core) * \param core a core * \param owner an optional owner of the global * \param type the type of the global - * \param version the version + * \param n_ifaces number of interfaces + * \param ifaces interface information * \param object the associated object * \param bind a function to bind to this global * \param[out] global a result global @@ -407,28 +424,29 @@ void pw_core_destroy(struct pw_core *core) */ bool pw_core_add_global(struct pw_core *core, - struct pw_resource *owner, + struct pw_resource *owner, uint32_t type, uint32_t version, - void *object, pw_bind_func_t bind, + void *object, struct pw_global **global) { struct global_impl *impl; struct pw_global *this; struct pw_resource *registry; + const char *type_name; impl = calloc(1, sizeof(struct global_impl)); if (impl == NULL) return false; this = &impl->this; - impl->bind = bind; this->core = core; this->owner = owner; this->type = type; this->version = version; + this->bind = bind; this->object = object; *global = this; @@ -439,11 +457,13 @@ pw_core_add_global(struct pw_core *core, spa_list_insert(core->global_list.prev, &this->link); pw_signal_emit(&core->global_added, core, this); - pw_log_debug("global %p: new %u %d, owner %p", this, this->id, this->type, owner); + type_name = spa_type_map_get_type(core->type.map, this->type); + + pw_log_debug("global %p: new %u %s, owner %p", this, this->id, type_name, owner); spa_list_for_each(registry, &core->registry_resource_list, link) if (pw_global_is_visible(this, registry->client)) - pw_registry_notify_global(registry, this->id, this->type, this->version); + pw_registry_resource_global(registry, this->id, this->type, this->version); return true; } @@ -462,18 +482,33 @@ pw_core_add_global(struct pw_core *core, * \memberof pw_global */ int -pw_global_bind(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id) +pw_global_bind(struct pw_global *global, struct pw_client *client, + uint32_t version, uint32_t id) { int res; - struct global_impl *impl = SPA_CONTAINER_OF(global, struct global_impl, this); - if (impl->bind) { - res = impl->bind(global, client, version, id); - } else { - res = SPA_RESULT_NOT_IMPLEMENTED; - pw_core_notify_error(client->core_resource, - client->core_resource->id, res, "can't bind object id %d", id); - } + if (global->bind == NULL) + goto no_bind; + + if (global->version < version) + goto wrong_version; + + res = global->bind(global, client, version, id); + + return res; + + wrong_version: + res = SPA_RESULT_INCOMPATIBLE_VERSION; + pw_core_resource_error(client->core_resource, + client->core_resource->id, + res, "id %d: interface version %d < %d", + id, global->version, version); + return res; + no_bind: + res = SPA_RESULT_NOT_IMPLEMENTED; + pw_core_resource_error(client->core_resource, + client->core_resource->id, + res, "can't bind object id %d to interface", id); return res; } @@ -493,7 +528,7 @@ void pw_global_destroy(struct pw_global *global) spa_list_for_each(registry, &core->registry_resource_list, link) if (pw_global_is_visible(global, registry->client)) - pw_registry_notify_global_remove(registry, global->id); + pw_registry_resource_global_remove(registry, global->id); pw_map_remove(&core->objects, global->id); @@ -534,7 +569,7 @@ void pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict pw_signal_emit(&core->info_changed, core); spa_list_for_each(resource, &core->resource_list, link) { - pw_core_notify_info(resource, &core->info); + pw_core_resource_info(resource, &core->info); } core->info.change_mask = 0; } diff --git a/src/pipewire/core.h b/src/pipewire/core.h index 1bd214979..94dd1b83e 100644 --- a/src/pipewire/core.h +++ b/src/pipewire/core.h @@ -37,12 +37,6 @@ struct pw_global; #include #include -#define PW_TYPE__Core PW_TYPE_OBJECT_BASE "Core" -#define PW_TYPE_CORE_BASE PW_TYPE__Core ":" - -#define PW_TYPE__Registry PW_TYPE_OBJECT_BASE "Registry" -#define PW_TYPE_REGISTRY_BASE PW_TYPE__Registry ":" - /** \page page_server_api Server API * * \section page_server_overview Overview @@ -96,8 +90,10 @@ struct pw_global; * emit events to the client and lets the client invoke methods on * the object. */ -typedef int (*pw_bind_func_t) (struct pw_global *global, - struct pw_client *client, uint32_t version, uint32_t id); +typedef int (*pw_bind_func_t) (struct pw_global *global, /**< the global to bind */ + struct pw_client *client, /**< client that binds */ + uint32_t version, /**< client interface version */ + uint32_t id); /**< client proxy id */ typedef bool (*pw_global_filter_func_t) (struct pw_global *global, struct pw_client *client, void *data); @@ -131,9 +127,12 @@ struct pw_global { struct spa_list link; /**< link in core list of globals */ uint32_t id; /**< server id of the object */ - uint32_t type; /**< type of the object */ - uint32_t version; /**< version of the object */ - void *object; /**< object associated with the global */ + + uint32_t type; /**< type of interface */ + uint32_t version; /**< version of interface */ + pw_bind_func_t bind; /**< function to bind to the interface */ + + void *object; /**< object associated with the interface */ /** Emited when the global is destroyed */ PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_global *global)); @@ -210,12 +209,15 @@ pw_core_add_global(struct pw_core *core, struct pw_resource *owner, uint32_t type, uint32_t version, - void *object, pw_bind_func_t bind, + pw_bind_func_t bind, + void *object, struct pw_global **global); int pw_global_bind(struct pw_global *global, - struct pw_client *client, uint32_t version, uint32_t id); + struct pw_client *client, + uint32_t version, + uint32_t id); void pw_global_destroy(struct pw_global *global); diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h index 8f472a0ca..8c5220aaa 100644 --- a/src/pipewire/interfaces.h +++ b/src/pipewire/interfaces.h @@ -30,7 +30,18 @@ extern "C" { #include #include +#include #include +#include +#include +#include + +struct pw_core_proxy { struct pw_proxy proxy; }; +struct pw_registry_proxy { struct pw_proxy proxy; }; +struct pw_module_proxy { struct pw_proxy proxy; }; +struct pw_node_proxy { struct pw_proxy proxy; }; +struct pw_client_proxy { struct pw_proxy proxy; }; +struct pw_link_proxy { struct pw_proxy proxy; }; /** * \page page_pipewire_protocol The PipeWire protocol @@ -48,7 +59,16 @@ extern "C" { * \section page_iface_pw_core API */ -#define PW_VERSION_CORE 0 +/** Core */ + +#define PW_TYPE_INTERFACE__Core PW_TYPE_INTERFACE_BASE "Core" +#define PW_TYPE_INTERFACE__Registry PW_TYPE_INTERFACE_BASE "Registry" +#define PW_TYPE_INTERFACE__Module PW_TYPE_INTERFACE_BASE "Module" +#define PW_TYPE_INTERFACE__Node PW_TYPE_INTERFACE_BASE "Node" +#define PW_TYPE_INTERFACE__Client PW_TYPE_INTERFACE_BASE "Client" +#define PW_TYPE_INTERFACE__Link PW_TYPE_INTERFACE_BASE "Link" + +#define PW_VERSION_CORE 0 #define PW_CORE_METHOD_UPDATE_TYPES 0 #define PW_CORE_METHOD_SYNC 1 @@ -67,6 +87,8 @@ extern "C" { * for internal features. */ struct pw_core_methods { +#define PW_VERSION_CORE_METHODS 0 + uint32_t version; /** * Update the type map * @@ -111,15 +133,17 @@ struct pw_core_methods { * * \param factory_name the factory name to use * \param name the node name - * \param props extra properties + * \param type the interface to bind to * \param version the version of the interface + * \param props extra properties * \param new_id the client proxy id */ void (*create_node) (void *object, const char *factory_name, const char *name, - const struct spa_dict *props, + uint32_t type, uint32_t version, + const struct spa_dict *props, uint32_t new_id); /** * Create a new link between two node ports @@ -142,12 +166,69 @@ struct pw_core_methods { uint32_t new_id); }; -#define pw_core_do_update_types(p,...) pw_proxy_do(p,struct pw_core_methods,update_types,__VA_ARGS__) -#define pw_core_do_sync(p,...) pw_proxy_do(p,struct pw_core_methods,sync,__VA_ARGS__) -#define pw_core_do_get_registry(p,...) pw_proxy_do(p,struct pw_core_methods,get_registry,__VA_ARGS__) -#define pw_core_do_client_update(p,...) pw_proxy_do(p,struct pw_core_methods,client_update,__VA_ARGS__) -#define pw_core_do_create_node(p,...) pw_proxy_do(p,struct pw_core_methods,create_node,__VA_ARGS__) -#define pw_core_do_create_link(p,...) pw_proxy_do(p,struct pw_core_methods,create_link,__VA_ARGS__) +static inline void +pw_core_proxy_update_types(struct pw_core_proxy *core, uint32_t first_id, uint32_t n_types, const char **types) +{ + pw_proxy_do(&core->proxy, struct pw_core_methods, update_types, first_id, n_types, types); +} + +static inline void +pw_core_proxy_sync(struct pw_core_proxy *core, uint32_t seq) +{ + pw_proxy_do(&core->proxy, struct pw_core_methods, sync, seq); +} + +static inline struct pw_registry_proxy * +pw_core_proxy_get_registry(struct pw_core_proxy *core, uint32_t version, size_t user_data_size, pw_destroy_t destroy) +{ + struct pw_core *c = core->proxy.remote->core; + struct pw_proxy *p = pw_proxy_new(core->proxy.remote, SPA_ID_INVALID, c->type.registry, + user_data_size, destroy); + pw_proxy_do(&core->proxy, struct pw_core_methods, get_registry, version, p->id); + return (struct pw_registry_proxy *) p; +} + +static inline void +pw_core_proxy_client_update(struct pw_core_proxy *core, const struct spa_dict *props) +{ + pw_proxy_do(&core->proxy, struct pw_core_methods, client_update, props); +} + +static inline void * +pw_core_proxy_create_node(struct pw_core_proxy *core, + const char *factory_name, + const char *name, + uint32_t type, + uint32_t version, + const struct spa_dict *props, + size_t user_data_size, + pw_destroy_t destroy) +{ + struct pw_proxy *p = pw_proxy_new(core->proxy.remote, SPA_ID_INVALID, type, user_data_size, destroy); + pw_proxy_do(&core->proxy, struct pw_core_methods, create_node, factory_name, + name, type, version, props, p->id); + return p; +} + +static inline struct pw_link_proxy * +pw_core_proxy_create_link(struct pw_core_proxy *core, + uint32_t output_node_id, + uint32_t output_port_id, + uint32_t input_node_id, + uint32_t input_port_id, + const struct spa_format *filter, + const struct spa_dict *prop, + size_t user_data_size, + pw_destroy_t destroy) +{ + struct pw_core *c = core->proxy.remote->core; + struct pw_proxy *p = pw_proxy_new(core->proxy.remote, SPA_ID_INVALID, c->type.link, + user_data_size, destroy); + pw_proxy_do(&core->proxy, struct pw_core_methods, create_link, output_node_id, output_port_id, + input_node_id, input_port_id, filter, prop, p->id); + return (struct pw_link_proxy*) p; +} + #define PW_CORE_EVENT_UPDATE_TYPES 0 #define PW_CORE_EVENT_DONE 1 @@ -161,6 +242,8 @@ struct pw_core_methods { * \ingroup pw_core_interface The pw_core interface */ struct pw_core_events { +#define PW_VERSION_CORE_EVENTS 0 + uint32_t version; /** * Update the type map * @@ -214,19 +297,31 @@ struct pw_core_events { void (*info) (void *object, struct pw_core_info *info); }; -#define pw_core_notify_update_types(r,...) pw_resource_notify(r,struct pw_core_events,update_types,__VA_ARGS__) -#define pw_core_notify_done(r,...) pw_resource_notify(r,struct pw_core_events,done,__VA_ARGS__) -#define pw_core_notify_error(r,...) pw_resource_notify(r,struct pw_core_events,error,__VA_ARGS__) -#define pw_core_notify_remove_id(r,...) pw_resource_notify(r,struct pw_core_events,remove_id,__VA_ARGS__) -#define pw_core_notify_info(r,...) pw_resource_notify(r,struct pw_core_events,info,__VA_ARGS__) +static inline void +pw_core_proxy_add_listener(struct pw_core_proxy *core, + void *object, const struct pw_core_events *events) +{ + pw_proxy_add_listener(&core->proxy, object, events); +} + + +#define pw_core_resource_update_types(r,...) pw_resource_notify(r,struct pw_core_events,update_types,__VA_ARGS__) +#define pw_core_resource_done(r,...) pw_resource_notify(r,struct pw_core_events,done,__VA_ARGS__) +#define pw_core_resource_error(r,...) pw_resource_notify(r,struct pw_core_events,error,__VA_ARGS__) +#define pw_core_resource_remove_id(r,...) pw_resource_notify(r,struct pw_core_events,remove_id,__VA_ARGS__) +#define pw_core_resource_info(r,...) pw_resource_notify(r,struct pw_core_events,info,__VA_ARGS__) + + #define PW_VERSION_REGISTRY 0 -#define PW_REGISTRY_METHOD_BIND 0 -#define PW_REGISTRY_METHOD_NUM 1 +#define PW_REGISTRY_METHOD_BIND 0 +#define PW_REGISTRY_METHOD_NUM 1 /** Registry methods */ struct pw_registry_methods { +#define PW_VERSION_REGISTRY_METHODS 0 + uint32_t version; /** * Bind to a global object * @@ -235,13 +330,24 @@ struct pw_registry_methods { * send to the remote global object and events can be received * * \param id the global id to bind to - * \param version the version to use + * \param type the interface type to bind to + * \param version the interface version to use * \param new_id the client proxy to use */ - void (*bind) (void *object, uint32_t id, uint32_t version, uint32_t new_id); + void (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id); }; -#define pw_registry_do_bind(p,...) pw_proxy_do(p,struct pw_registry_methods,bind,__VA_ARGS__) +/** Registry */ +static inline void * +pw_registry_proxy_bind(struct pw_registry_proxy *registry, + uint32_t id, uint32_t type, uint32_t version, + size_t user_data_size, pw_destroy_t destroy) +{ + struct pw_proxy *p = pw_proxy_new(registry->proxy.remote, SPA_ID_INVALID, + type, user_data_size, destroy); + pw_proxy_do(®istry->proxy, struct pw_registry_methods, bind, id, type, version, p->id); + return p; +} #define PW_REGISTRY_EVENT_GLOBAL 0 #define PW_REGISTRY_EVENT_GLOBAL_REMOVE 1 @@ -249,6 +355,8 @@ struct pw_registry_methods { /** Registry events */ struct pw_registry_events { +#define PW_VERSION_REGISTRY_EVENTS 0 + uint32_t version; /** * Notify of a new global object * @@ -256,8 +364,8 @@ struct pw_registry_events { * available. * * \param id the global object id - * \param type the type of the object - * \param version the version of the object + * \param type the type of the interface + * \param version the version of the interface */ void (*global) (void *object, uint32_t id, uint32_t type, uint32_t version); /** @@ -272,8 +380,16 @@ struct pw_registry_events { void (*global_remove) (void *object, uint32_t id); }; -#define pw_registry_notify_global(r,...) pw_resource_notify(r,struct pw_registry_events,global,__VA_ARGS__) -#define pw_registry_notify_global_remove(r,...) pw_resource_notify(r,struct pw_registry_events,global_remove,__VA_ARGS__) +static inline void +pw_registry_proxy_add_listener(struct pw_registry_proxy *registry, + void *object, const struct pw_registry_events *events) +{ + pw_proxy_add_listener(®istry->proxy, object, events); +} + +#define pw_registry_resource_global(r,...) pw_resource_notify(r,struct pw_registry_events,global,__VA_ARGS__) +#define pw_registry_resource_global_remove(r,...) pw_resource_notify(r,struct pw_registry_events,global_remove,__VA_ARGS__) + #define PW_VERSION_MODULE 0 @@ -282,6 +398,8 @@ struct pw_registry_events { /** Module events */ struct pw_module_events { +#define PW_VERSION_MODULE_EVENTS 0 + uint32_t version; /** * Notify module info * @@ -290,15 +408,24 @@ struct pw_module_events { void (*info) (void *object, struct pw_module_info *info); }; -#define pw_module_notify_info(r,...) pw_resource_notify(r,struct pw_module_events,info,__VA_ARGS__) +static inline void +pw_module_proxy_add_listener(struct pw_module_proxy *module, + void *object, const struct pw_module_events *events) +{ + pw_proxy_add_listener(&module->proxy, object, events); +} -#define PW_VERSION_NODE 0 +#define pw_module_resource_info(r,...) pw_resource_notify(r,struct pw_module_events,info,__VA_ARGS__) + +#define PW_VERSION_NODE 0 #define PW_NODE_EVENT_INFO 0 #define PW_NODE_EVENT_NUM 1 /** Node events */ struct pw_node_events { +#define PW_VERSION_NODE_EVENTS 0 + uint32_t version; /** * Notify node info * @@ -307,7 +434,14 @@ struct pw_node_events { void (*info) (void *object, struct pw_node_info *info); }; -#define pw_node_notify_info(r,...) pw_resource_notify(r,struct pw_node_events,info,__VA_ARGS__) +static inline void +pw_node_proxy_add_listener(struct pw_node_proxy *node, + void *object, const struct pw_node_events *events) +{ + pw_proxy_add_listener(&node->proxy, object, events); +} + +#define pw_node_resource_info(r,...) pw_resource_notify(r,struct pw_node_events,info,__VA_ARGS__) #define PW_VERSION_CLIENT 0 @@ -316,6 +450,8 @@ struct pw_node_events { /** Client events */ struct pw_client_events { +#define PW_VERSION_CLIENT_EVENTS 0 + uint32_t version; /** * Notify client info * @@ -324,15 +460,26 @@ struct pw_client_events { void (*info) (void *object, struct pw_client_info *info); }; -#define pw_client_notify_info(r,...) pw_resource_notify(r,struct pw_client_events,info,__VA_ARGS__) +/** Client */ +static inline void +pw_client_proxy_add_listener(struct pw_client_proxy *client, + void *object, const struct pw_client_events *events) +{ + pw_proxy_add_listener(&client->proxy, object, events); +} -#define PW_VERSION_LINK 0 +#define pw_client_resource_info(r,...) pw_resource_notify(r,struct pw_client_events,info,__VA_ARGS__) + + +#define PW_VERSION_LINK 0 #define PW_LINK_EVENT_INFO 0 #define PW_LINK_EVENT_NUM 1 /** Link events */ struct pw_link_events { +#define PW_VERSION_LINK_EVENTS 0 + uint32_t version; /** * Notify link info * @@ -341,7 +488,15 @@ struct pw_link_events { void (*info) (void *object, struct pw_link_info *info); }; -#define pw_link_notify_info(r,...) pw_resource_notify(r,struct pw_link_events,info,__VA_ARGS__) +/** Link */ +static inline void +pw_link_proxy_add_listener(struct pw_link_proxy *link, + void *object, const struct pw_link_events *events) +{ + pw_proxy_add_listener(&link->proxy, object, events); +} + +#define pw_link_resource_info(r,...) pw_resource_notify(r,struct pw_link_events,info,__VA_ARGS__) #ifdef __cplusplus } /* extern "C" */ diff --git a/src/pipewire/introspect.c b/src/pipewire/introspect.c index 02e4b8112..e6d0d7cc8 100644 --- a/src/pipewire/introspect.c +++ b/src/pipewire/introspect.c @@ -125,7 +125,6 @@ struct pw_core_info *pw_core_info_update(struct pw_core_info *info, if (info == NULL) return NULL; } - info->id = update->id; info->change_mask = update->change_mask; if (update->change_mask & (1 << 0)) { @@ -186,7 +185,6 @@ struct pw_node_info *pw_node_info_update(struct pw_node_info *info, if (info == NULL) return NULL; } - info->id = update->id; info->change_mask = update->change_mask; if (update->change_mask & (1 << 0)) { @@ -283,7 +281,6 @@ struct pw_module_info *pw_module_info_update(struct pw_module_info *info, if (info == NULL) return NULL; } - info->id = update->id; info->change_mask = update->change_mask; if (update->change_mask & (1 << 0)) { @@ -334,7 +331,6 @@ struct pw_client_info *pw_client_info_update(struct pw_client_info *info, if (info == NULL) return NULL; } - info->id = update->id; info->change_mask = update->change_mask; if (update->change_mask & (1 << 0)) { @@ -363,7 +359,6 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info, if (info == NULL) return NULL; } - info->id = update->id; info->change_mask = update->change_mask; if (update->change_mask & (1 << 0)) diff --git a/src/pipewire/introspect.h b/src/pipewire/introspect.h index dd0d772ec..68e272d02 100644 --- a/src/pipewire/introspect.h +++ b/src/pipewire/introspect.h @@ -74,7 +74,6 @@ const char * pw_link_state_as_string(enum pw_link_state state); /** The core information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_core_info { - uint32_t id; /**< server side id of the core */ #define PW_CORE_CHANGE_MASK_USER_NAME (1 << 0) #define PW_CORE_CHANGE_MASK_HOST_NAME (1 << 1) #define PW_CORE_CHANGE_MASK_VERSION (1 << 2) @@ -101,7 +100,6 @@ void pw_core_info_free(struct pw_core_info *info); /** The module information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_module_info { - uint32_t id; /**< server side id of the module */ uint64_t change_mask; /**< bitfield of changed fields since last call */ const char *name; /**< name of the module */ const char *filename; /**< filename of the module */ @@ -119,7 +117,6 @@ void pw_module_info_free(struct pw_module_info *info); /** The client information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_client_info { - uint32_t id; /**< server side id of the client */ uint64_t change_mask; /**< bitfield of changed fields since last call */ struct spa_dict *props; /**< extra properties */ }; @@ -135,7 +132,6 @@ void pw_client_info_free(struct pw_client_info *info); /** The node information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_node_info { - uint32_t id; /**< server side id of the node */ uint64_t change_mask; /**< bitfield of changed fields since last call */ const char *name; /**< name the node, suitable for display */ uint32_t max_input_ports; /**< maximum number of inputs */ @@ -161,7 +157,6 @@ pw_node_info_free(struct pw_node_info *info); /** The link information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_link_info { - uint32_t id; /**< server side id of the link */ uint64_t change_mask; /**< bitfield of changed fields since last call */ uint32_t output_node_id; /**< server side output node id */ uint32_t output_port_id; /**< output port id */ diff --git a/src/pipewire/link.c b/src/pipewire/link.c index b9279ffdf..d69f96c2a 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -939,31 +939,34 @@ static void link_unbind_func(void *data) } static int -link_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id) +link_bind_func(struct pw_global *global, + struct pw_client *client, + uint32_t version, uint32_t id) { struct pw_link *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, version, 0); + resource = pw_resource_new(client, id, global->type, version, 0, link_unbind_func); if (resource == NULL) goto no_mem; - pw_resource_set_implementation(resource, global->object, PW_VERSION_LINK, NULL, link_unbind_func); + pw_resource_set_implementation(resource, this, NULL); - pw_log_debug("link %p: bound to %d", global->object, resource->id); + pw_log_debug("link %p: bound to %d", this, resource->id); spa_list_insert(this->resource_list.prev, &resource->link); this->info.change_mask = ~0; - pw_link_notify_info(resource, &this->info); + pw_link_resource_info(resource, &this->info); + this->info.change_mask = 0; return SPA_RESULT_OK; no_mem: pw_log_error("can't create link resource"); - pw_core_notify_error(client->core_resource, - client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); + pw_core_resource_error(client->core_resource, + client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); return SPA_RESULT_NO_MEMORY; } @@ -1054,9 +1057,8 @@ struct pw_link *pw_link_new(struct pw_core *core, spa_list_insert(core->link_list.prev, &this->link); pw_core_add_global(core, NULL, core->type.link, PW_VERSION_LINK, - this, link_bind_func, &this->global); + link_bind_func, this, &this->global); - this->info.id = this->global->id; this->info.output_node_id = output ? output_node->global->id : -1; this->info.output_port_id = output ? output->port_id : -1; this->info.input_node_id = input ? input_node->global->id : -1; diff --git a/src/pipewire/module.c b/src/pipewire/module.c index f37958d65..d7c2af1a9 100644 --- a/src/pipewire/module.c +++ b/src/pipewire/module.c @@ -88,28 +88,31 @@ static char *find_module(const char *path, const char *name) } static int -module_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id) +module_bind_func(struct pw_global *global, + struct pw_client *client, + uint32_t version, uint32_t id) { struct pw_module *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, version, 0); + resource = pw_resource_new(client, id, global->type, version, 0, NULL); if (resource == NULL) goto no_mem; - pw_resource_set_implementation(resource, global->object, PW_VERSION_MODULE, NULL, NULL); + pw_resource_set_implementation(resource, this, NULL); - pw_log_debug("module %p: bound to %d", global->object, resource->id); + pw_log_debug("module %p: bound to %d", this, resource->id); this->info.change_mask = ~0; - pw_module_notify_info(resource, &this->info); + pw_module_resource_info(resource, &this->info); + this->info.change_mask = 0; return SPA_RESULT_OK; no_mem: pw_log_error("can't create module resource"); - pw_core_notify_error(client->core_resource, - client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); + pw_core_resource_error(client->core_resource, + client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); return SPA_RESULT_NO_MEMORY; } @@ -181,9 +184,8 @@ struct pw_module *pw_module_load(struct pw_core *core, goto init_failed; pw_core_add_global(core, NULL, core->type.module, PW_VERSION_MODULE, - impl, module_bind_func, &this->global); + module_bind_func, this, &this->global); - this->info.id = this->global->id; this->info.name = name ? strdup(name) : NULL; this->info.filename = filename; this->info.args = args ? strdup(args) : NULL; diff --git a/src/pipewire/node-factory.h b/src/pipewire/node-factory.h index b343e319f..808ce31ab 100644 --- a/src/pipewire/node-factory.h +++ b/src/pipewire/node-factory.h @@ -24,8 +24,8 @@ extern "C" { #endif -#define PW_TYPE__NodeFactory "PipeWire:Object:NodeFactory" -#define PW_TYPE_NODE_FACTORY_BASE PW_TYPE__NodeFactory ":" +#define PW_TYPE_INTERFACE__NodeFactory PW_TYPE_INTERFACE_BASE "NodeFactory" +#define PW_TYPE_NODE_FACTORY_BASE PW_TYPE_INTERFACE__NodeFactory ":" #include #include @@ -42,7 +42,6 @@ struct pw_node_factory { struct pw_global *global; /**< global for this factory */ const char *name; /**< the factory name */ - uint32_t type; /**< type of the created nodes */ /** Emited when the factory is destroyed */ PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_node_factory *object)); diff --git a/src/pipewire/node.c b/src/pipewire/node.c index dc7f1f5d5..bfd6e1605 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -151,7 +151,6 @@ static void node_unbind_func(void *data) static void update_info(struct pw_node *this) { - this->info.id = this->global->id; this->info.input_formats = NULL; if (!spa_list_is_empty(&this->input_ports)) { @@ -211,31 +210,33 @@ clear_info(struct pw_node *this) } static int -node_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id) +node_bind_func(struct pw_global *global, + struct pw_client *client, + uint32_t version, uint32_t id) { struct pw_node *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, version, 0); + resource = pw_resource_new(client, id, global->type, version, 0, node_unbind_func); if (resource == NULL) goto no_mem; - pw_resource_set_implementation(resource, global->object, PW_VERSION_NODE, NULL, node_unbind_func); + pw_resource_set_implementation(resource, this, NULL); pw_log_debug("node %p: bound to %d", this, resource->id); spa_list_insert(this->resource_list.prev, &resource->link); this->info.change_mask = ~0; - pw_node_notify_info(resource, &this->info); + pw_node_resource_info(resource, &this->info); this->info.change_mask = 0; return SPA_RESULT_OK; no_mem: pw_log_error("can't create node resource"); - pw_core_notify_error(client->core_resource, - client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); + pw_core_resource_error(client->core_resource, + client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); return SPA_RESULT_NO_MEMORY; } @@ -250,6 +251,7 @@ do_node_add(struct spa_loop *loop, return SPA_RESULT_OK; } + void pw_node_export(struct pw_node *this) { struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); @@ -259,7 +261,7 @@ void pw_node_export(struct pw_node *this) spa_list_insert(this->core->node_list.prev, &this->link); pw_core_add_global(this->core, this->owner, this->core->type.node, PW_VERSION_NODE, - this, node_bind_func, &this->global); + node_bind_func, this, &this->global); pw_loop_invoke(this->data_loop, do_node_add, 1, 0, NULL, false, this); @@ -611,7 +613,7 @@ void pw_node_update_state(struct pw_node *node, enum pw_node_state state, char * node->info.change_mask |= 1 << 5; spa_list_for_each(resource, &node->resource_list, link) - pw_node_notify_info(resource, &node->info); + pw_node_resource_info(resource, &node->info); node->info.change_mask = 0; } } diff --git a/src/pipewire/node.h b/src/pipewire/node.h index fcca866e0..20e3b9c1f 100644 --- a/src/pipewire/node.h +++ b/src/pipewire/node.h @@ -42,10 +42,8 @@ extern "C" { struct pw_node; - -#define PW_VERSION_NODE_IMPLEMENTATION 0 - struct pw_node_implementation { +#define PW_VERSION_NODE_IMPLEMENTATION 0 uint32_t version; int (*get_props) (struct pw_node *node, struct spa_props **props); @@ -71,8 +69,6 @@ struct pw_node_implementation { * The node object processes data. The node has a list of * input and output ports (\ref page_port) on which it * will receive and send out buffers respectively. - * - * The node wraps an SPA node object. */ /** \class pw_node * diff --git a/src/pipewire/protocol.c b/src/pipewire/protocol.c index bf2564251..02df317ba 100644 --- a/src/pipewire/protocol.c +++ b/src/pipewire/protocol.c @@ -23,6 +23,12 @@ struct impl { struct pw_protocol this; }; +struct marshal { + struct spa_list link; + const struct pw_protocol_marshal *marshal; + uint32_t type; +}; + struct pw_protocol *pw_protocol_new(struct pw_core *core, const char *name, size_t user_data_size) @@ -36,7 +42,7 @@ struct pw_protocol *pw_protocol_new(struct pw_core *core, protocol->core = core; protocol->name = strdup(name); - spa_list_init(&protocol->iface_list); + spa_list_init(&protocol->marshal_list); spa_list_init(&protocol->connection_list); spa_list_init(&protocol->listener_list); @@ -55,7 +61,7 @@ struct pw_protocol *pw_protocol_new(struct pw_core *core, void pw_protocol_destroy(struct pw_protocol *protocol) { struct impl *impl = SPA_CONTAINER_OF(protocol, struct impl, this); - struct pw_protocol_iface *iface, *t1; + struct marshal *marshal, *t1; struct pw_protocol_listener *listener, *t2; struct pw_protocol_connection *connection, *t3; @@ -64,8 +70,8 @@ void pw_protocol_destroy(struct pw_protocol *protocol) spa_list_remove(&protocol->link); - spa_list_for_each_safe(iface, t1, &protocol->iface_list, link) - free(iface); + spa_list_for_each_safe(marshal, t1, &protocol->marshal_list, link) + free(marshal); spa_list_for_each_safe(listener, t2, &protocol->listener_list, link) pw_protocol_listener_destroy(listener); @@ -82,41 +88,31 @@ void pw_protocol_destroy(struct pw_protocol *protocol) } void -pw_protocol_add_interfaces(struct pw_protocol *protocol, - const struct pw_interface *client_iface, - const struct pw_interface *server_iface) +pw_protocol_add_marshal(struct pw_protocol *protocol, + const struct pw_protocol_marshal *marshal) { - struct pw_protocol_iface *iface; - const char *type; - uint32_t version; + struct marshal *impl; - iface = calloc(1, sizeof(struct pw_protocol_iface)); - iface->client_iface = client_iface; - iface->server_iface = server_iface; + impl = calloc(1, sizeof(struct marshal)); + impl->marshal = marshal; + impl->type = spa_type_map_get_id (protocol->core->type.map, marshal->type); - spa_list_insert(protocol->iface_list.prev, &iface->link); + spa_list_insert(protocol->marshal_list.prev, &impl->link); - type = client_iface ? client_iface->type : server_iface->type; - version = client_iface ? client_iface->version : server_iface->version; - - pw_log_info("Add iface %s:%d to protocol %s", type, version, protocol->name); + pw_log_info("Add marshal %s:%d to protocol %s", marshal->type, marshal->version, protocol->name); } -const struct pw_interface * -pw_protocol_get_interface(struct pw_protocol *protocol, - const char *type, - bool server) +const struct pw_protocol_marshal * +pw_protocol_get_marshal(struct pw_protocol *protocol, uint32_t type) { - struct pw_protocol_iface *protocol_iface; + struct marshal *impl; if (protocol == NULL) return NULL; - spa_list_for_each(protocol_iface, &protocol->iface_list, link) { - const struct pw_interface *iface = server ? protocol_iface->server_iface : - protocol_iface->client_iface; - if (strcmp(iface->type, type) == 0) - return iface; + spa_list_for_each(impl, &protocol->marshal_list, link) { + if (impl->type == type) + return impl->marshal; } return NULL; } diff --git a/src/pipewire/protocol.h b/src/pipewire/protocol.h index 8d383c087..56f49059b 100644 --- a/src/pipewire/protocol.h +++ b/src/pipewire/protocol.h @@ -63,10 +63,15 @@ struct pw_protocol_listener { #define pw_protocol_listener_destroy(l) ((l)->destroy(l)) -struct pw_protocol_iface { - struct spa_list link; - const struct pw_interface *client_iface; - const struct pw_interface *server_iface; +struct pw_protocol_marshal { + const char *type; /**< interface type */ + uint32_t version; /**< version */ + uint32_t n_methods; /**< number of methods in the interface */ + const void *method_marshal; + const void *method_demarshal; + uint32_t n_events; /**< number of events in the interface */ + const void *event_marshal; + const void *event_demarshal; }; struct pw_protocol_implementaton { @@ -86,7 +91,7 @@ struct pw_protocol { char *name; /**< type name of the protocol */ - struct spa_list iface_list; /**< list of supported interfaces */ + struct spa_list marshal_list; /**< list of marshallers for supported interfaces */ struct spa_list connection_list; /**< list of current connections */ struct spa_list listener_list; /**< list of current listeners */ @@ -104,9 +109,7 @@ struct pw_protocol { #define pw_protocol_new_connection(p,...) ((p)->implementation->new_connection(p,__VA_ARGS__)) #define pw_protocol_add_listener(p,...) ((p)->implementation->add_listener(p,__VA_ARGS__)) -#define pw_protocol_ext(p,type,method,...) ((type*)(p)->extension)->method( __VA_ARGS__) -#define pw_protocol_connection_ext(c,type,method,...) ((type*)(c)->protocol->extension)->method( __VA_ARGS__) -#define pw_protocol_listener_ext(l,type,method,...) ((type*)(l)->protocol->extension)->method( __VA_ARGS__) +#define pw_protocol_ext(p,type,method,...) (((type*)(p)->extension)->method( __VA_ARGS__)) struct pw_protocol *pw_protocol_new(struct pw_core *core, const char *name, size_t user_data_size); @@ -114,13 +117,11 @@ struct pw_protocol *pw_protocol_new(struct pw_core *core, const char *name, size * * \brief Manages protocols and their implementation */ -void -pw_protocol_add_interfaces(struct pw_protocol *protocol, - const struct pw_interface *client_iface, - const struct pw_interface *server_iface); +void pw_protocol_add_marshal(struct pw_protocol *protocol, + const struct pw_protocol_marshal *marshal); -const struct pw_interface * -pw_protocol_get_interface(struct pw_protocol *protocol, const char *type, bool server); +const struct pw_protocol_marshal * +pw_protocol_get_marshal(struct pw_protocol *protocol, uint32_t type); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/pipewire/proxy.c b/src/pipewire/proxy.c index db406bb2e..e5a48b151 100644 --- a/src/pipewire/proxy.c +++ b/src/pipewire/proxy.c @@ -20,6 +20,7 @@ #include #include #include +#include /** \cond */ struct proxy { @@ -42,8 +43,10 @@ struct proxy { * \memberof pw_proxy */ struct pw_proxy *pw_proxy_new(struct pw_remote *remote, - uint32_t id, uint32_t type, - size_t user_data_size) + uint32_t id, + uint32_t type, + size_t user_data_size, + pw_destroy_t destroy) { struct proxy *impl; struct pw_proxy *this; @@ -54,7 +57,6 @@ struct pw_proxy *pw_proxy_new(struct pw_remote *remote, this = &impl->this; this->remote = remote; - this->type = type; pw_signal_init(&this->destroy_signal); @@ -64,13 +66,13 @@ struct pw_proxy *pw_proxy_new(struct pw_remote *remote, goto in_use; this->id = id; + this->type = type; + this->destroy = destroy; if (user_data_size > 0) this->user_data = SPA_MEMBER(impl, sizeof(struct proxy), void); - this->iface = pw_protocol_get_interface(remote->conn->protocol, - spa_type_map_get_type(remote->core->type.map, type), - false); + this->marshal = pw_protocol_get_marshal(remote->conn->protocol, type); spa_list_insert(&this->remote->proxy_list, &this->link); @@ -84,17 +86,11 @@ struct pw_proxy *pw_proxy_new(struct pw_remote *remote, return NULL; } -int pw_proxy_set_implementation(struct pw_proxy *proxy, - void *object, - uint32_t version, - const void *implementation, - pw_destroy_t destroy) +void pw_proxy_add_listener(struct pw_proxy *proxy, + void *object, const void *listener) { proxy->object = object; - proxy->version = version; - proxy->implementation = implementation; - proxy->destroy = destroy; - return SPA_RESULT_OK; + proxy->listener = listener; } /** Destroy a proxy object diff --git a/src/pipewire/proxy.h b/src/pipewire/proxy.h index 665535766..94b6215d6 100644 --- a/src/pipewire/proxy.h +++ b/src/pipewire/proxy.h @@ -26,7 +26,8 @@ extern "C" { #include #include -#include + +struct pw_remote; /** \page page_proxy Proxy * @@ -82,7 +83,7 @@ extern "C" { * A pw_proxy acts as a client side proxy to an object existing in the * pipewire server. The proxy is responsible for converting interface functions * invoked by the client to PipeWire messages. Events will call the handlers - * set in implementation. + * set in listener. * * See \ref page_proxy */ @@ -91,39 +92,40 @@ struct pw_proxy { struct spa_list link; /**< link in the remote */ uint32_t id; /**< client side id */ - uint32_t type; /**< object type id */ - const struct pw_interface *iface; /**< methods/events marshal/demarshal functions */ + uint32_t type; /**< type id */ - void *object; /**< client side object */ - uint32_t version; - const void *implementation; /**< event handler implementation */ - pw_destroy_t destroy; /**< optional destroy function to clean up the object */ + const void *listener; /**< event listener */ + void *object; /**< object associated with proxy */ + + const struct pw_protocol_marshal *marshal; /**< protocol specific marshal functions */ /** destroy is emited when the proxy is destroyed */ PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_proxy *proxy)); void *user_data; /**< extra user data */ + pw_destroy_t destroy; /**< optional destroy function to clean up the user_data */ }; +/** Make a new proxy object. The id can be used to bind to a remote object. */ struct pw_proxy * -pw_proxy_new(struct pw_remote *remote, - uint32_t id, - uint32_t type, - size_t user_data_size); +pw_proxy_new(struct pw_remote *remote, /**< remote this proxy is from */ + uint32_t id, /**< local id, SPA_ID_INVALID to have one automatically + * allocated for you */ + uint32_t type, /**< interface type id */ + size_t user_data_size, /**< size of user data */ + pw_destroy_t destroy /**< destroy function for user data */); -int -pw_proxy_set_implementation(struct pw_proxy *proxy, - void *object, - uint32_t version, - const void *implementation, - pw_destroy_t destroy); +void +pw_proxy_add_listener(struct pw_proxy *proxy, /**< the proxy */ + void *object, /**< object associated with proxy */ + const void *events /**< events */); void pw_proxy_destroy(struct pw_proxy *proxy); -#define pw_proxy_notify(p,type,event,...) ((type*) (p)->implementation)->event(p, __VA_ARGS__) -#define pw_proxy_notify_na(p,type,event) ((type*) (p)->implementation)->event(p) -#define pw_proxy_do(p,type,method,...) ((type*) (p)->iface->methods)->method(p, __VA_ARGS__) -#define pw_proxy_do_na(p,type,method) ((type*) (p)->iface->methods)->method(p) +#define pw_proxy_notify(p,type,event,...) ((type*) (p)->listener)->event(p, __VA_ARGS__) +#define pw_proxy_notify_na(p,type,event) ((type*) (p)->listener)->event(p) +#define pw_proxy_do(p,type,method,...) ((type*) (p)->marshal->method_marshal)->method(p, __VA_ARGS__) +#define pw_proxy_do_na(p,type,method) ((type*) (p)->marshal->method_marshal)->method(p) #ifdef __cplusplus } diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index 222ad090c..90f44bd95 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -87,7 +87,7 @@ remote_update_state(struct pw_remote *remote, enum pw_remote_state state, const static void core_event_info(void *object, struct pw_core_info *info) { struct pw_proxy *proxy = object; - struct pw_remote *this = proxy->remote; + struct pw_remote *this = proxy->object; pw_log_debug("got core info"); this->info = pw_core_info_update(this->info, info); @@ -97,7 +97,7 @@ static void core_event_info(void *object, struct pw_core_info *info) static void core_event_done(void *object, uint32_t seq) { struct pw_proxy *proxy = object; - struct pw_remote *this = proxy->remote; + struct pw_remote *this = proxy->object; pw_log_debug("core event done %d", seq); if (seq == 0) @@ -109,15 +109,14 @@ static void core_event_done(void *object, uint32_t seq) static void core_event_error(void *object, uint32_t id, int res, const char *error, ...) { struct pw_proxy *proxy = object; - struct pw_remote *this = proxy->remote; + struct pw_remote *this = proxy->object; remote_update_state(this, PW_REMOTE_STATE_ERROR, error); } static void core_event_remove_id(void *object, uint32_t id) { - struct pw_proxy *core_proxy = object; - struct pw_remote *this = core_proxy->remote; - struct pw_proxy *proxy; + struct pw_proxy *proxy = object; + struct pw_remote *this = proxy->object; proxy = pw_map_lookup(&this->objects, id); if (proxy) { @@ -130,7 +129,7 @@ static void core_event_update_types(void *object, uint32_t first_id, uint32_t n_types, const char **types) { struct pw_proxy *proxy = object; - struct pw_remote *this = proxy->remote; + struct pw_remote *this = proxy->object; int i; for (i = 0; i < n_types; i++, first_id++) { @@ -141,6 +140,7 @@ core_event_update_types(void *object, uint32_t first_id, uint32_t n_types, const } static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, &core_event_update_types, &core_event_done, &core_event_error, @@ -230,15 +230,14 @@ void pw_remote_destroy(struct pw_remote *remote) static int do_connect(struct pw_remote *remote) { - remote->core_proxy = pw_proxy_new(remote, 0, remote->core->type.core, 0); + remote->core_proxy = (struct pw_core_proxy*)pw_proxy_new(remote, 0, remote->core->type.core, 0, NULL); if (remote->core_proxy == NULL) goto no_proxy; - pw_proxy_set_implementation(remote->core_proxy, remote, PW_VERSION_CORE, - &core_events, NULL); + pw_proxy_add_listener((struct pw_proxy*)remote->core_proxy, remote, &core_events); - pw_core_do_client_update(remote->core_proxy, &remote->properties->dict); - pw_core_do_sync(remote->core_proxy, 0); + pw_core_proxy_client_update(remote->core_proxy, &remote->properties->dict); + pw_core_proxy_sync(remote->core_proxy, 0); return 0; diff --git a/src/pipewire/remote.h b/src/pipewire/remote.h index 7046fd77c..dad2a062d 100644 --- a/src/pipewire/remote.h +++ b/src/pipewire/remote.h @@ -24,8 +24,6 @@ extern "C" { #endif -struct pw_remote; - #include #include #include @@ -123,7 +121,7 @@ struct pw_remote { struct spa_list link; /**< link in core remote_list */ struct pw_properties *properties; /**< extra properties */ - struct pw_proxy *core_proxy; /**< proxy for the core object */ + struct pw_core_proxy *core_proxy; /**< proxy for the core object */ struct pw_map objects; /**< map of client side proxy objects * indexed with the client id */ struct pw_core_info *info; /**< info about the remote core */ diff --git a/src/pipewire/resource.c b/src/pipewire/resource.c index 0afce099b..245d5e96e 100644 --- a/src/pipewire/resource.c +++ b/src/pipewire/resource.c @@ -32,8 +32,9 @@ struct impl { struct pw_resource *pw_resource_new(struct pw_client *client, uint32_t id, uint32_t type, - uint32_t client_version, - size_t user_data_size) + uint32_t version, + size_t user_data_size, + pw_destroy_t destroy) { struct impl *impl; struct pw_resource *this; @@ -46,7 +47,7 @@ struct pw_resource *pw_resource_new(struct pw_client *client, this->core = client->core; this->client = client; this->type = type; - this->client_version = client_version; + this->version = version; pw_signal_init(&this->destroy_signal); @@ -60,9 +61,9 @@ struct pw_resource *pw_resource_new(struct pw_client *client, if (user_data_size > 0) this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void); - this->iface = pw_protocol_get_interface(client->protocol, - spa_type_map_get_type(client->core->type.map, type), - true); + this->destroy = destroy; + + this->marshal = pw_protocol_get_marshal(client->protocol, type); pw_log_debug("resource %p: new for client %p id %u", this, client, id); pw_signal_emit(&client->resource_added, client, this); @@ -77,17 +78,12 @@ struct pw_resource *pw_resource_new(struct pw_client *client, int pw_resource_set_implementation(struct pw_resource *resource, - void *object, - uint32_t version, - const void *implementation, - pw_destroy_t destroy) + void *object, const void *implementation) { struct pw_client *client = resource->client; resource->object = object; - resource->version = version; resource->implementation = implementation; - resource->destroy = destroy; pw_signal_emit(&client->resource_impl, client, resource); return SPA_RESULT_OK; @@ -107,7 +103,7 @@ void pw_resource_destroy(struct pw_resource *resource) resource->destroy(resource); if (client->core_resource) - pw_core_notify_remove_id(client->core_resource, resource->id); + pw_core_resource_remove_id(client->core_resource, resource->id); free(resource); } diff --git a/src/pipewire/resource.h b/src/pipewire/resource.h index 7a3767f97..8e85f9014 100644 --- a/src/pipewire/resource.h +++ b/src/pipewire/resource.h @@ -64,15 +64,16 @@ struct pw_resource { struct pw_client *client; /**< owner client */ uint32_t id; /**< per client unique id, index in client objects */ - uint32_t type; /**< type id of the object */ - uint32_t client_version; /**< version of the client interface */ - const struct pw_interface *iface; /**< protocol specific interface functions */ + uint32_t type; /**< type of the client interface */ + uint32_t version; /**< version of the client interface */ + + void *object; + const void *implementation; - void *object; /**< pointer to the object */ - uint32_t version; /**< interface version */ - const void *implementation; /**< method implementation */ pw_destroy_t destroy; /**< function to clean up the object */ + const struct pw_protocol_marshal *marshal; + /** Emited when the resource is destroyed */ PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_resource *resource)); @@ -80,27 +81,27 @@ struct pw_resource { void *user_data; /**< extra user data */ }; +/** Make a new resource for client */ struct pw_resource * -pw_resource_new(struct pw_client *client, - uint32_t id, - uint32_t type, - uint32_t client_version, - size_t user_data_size); +pw_resource_new(struct pw_client *client, /**< the client owning the resource */ + uint32_t id, /**< the remote per client id */ + uint32_t type, /**< interface of the resource */ + uint32_t version, /**< requested interface version */ + size_t user_data_size, /**< extra user data size */ + pw_destroy_t destroy /**< destroy function for user data */); + int pw_resource_set_implementation(struct pw_resource *resource, - void *object, - uint32_t version, - const void *implementation, - pw_destroy_t destroy); + void *object, const void *implementation); void pw_resource_destroy(struct pw_resource *resource); #define pw_resource_do(r,type,method,...) ((type*) r->implementation)->method(r, __VA_ARGS__) #define pw_resource_do_na(r,type,method) ((type*) r->implementation)->method(r) -#define pw_resource_notify(r,type,event,...) ((type*) r->iface->events)->event(r, __VA_ARGS__) -#define pw_resource_notify_na(r,type,event) ((type*) r->iface->events)->event(r) +#define pw_resource_notify(r,type,event,...) ((type*) r->marshal->event_marshal)->event(r, __VA_ARGS__) +#define pw_resource_notify_na(r,type,event) ((type*) r->marshal->event_marshal)->event(r) #ifdef __cplusplus } diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 75e03bbe4..b1f7a3762 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -82,7 +82,7 @@ struct stream { int rtwritefd; struct spa_source *rtsocket_source; - struct pw_proxy *node_proxy; + struct pw_client_node_proxy *node_proxy; bool disconnecting; struct pw_listener node_proxy_destroy; struct pw_listener node_proxy_sync_done; @@ -204,7 +204,7 @@ struct pw_stream *pw_stream_new(struct pw_remote *remote, this->remote = remote; this->name = strdup(name); - impl->type_client_node = spa_type_map_get_id(remote->core->type.map, PW_TYPE__ClientNode); + impl->type_client_node = spa_type_map_get_id(remote->core->type.map, PW_TYPE_INTERFACE__ClientNode); pw_signal_init(&this->destroy_signal); pw_signal_init(&this->state_changed); @@ -340,8 +340,8 @@ static void add_node_update(struct pw_stream *stream, uint32_t change_mask) if (change_mask & PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS) max_output_ports = impl->direction == SPA_DIRECTION_OUTPUT ? 1 : 0; - pw_client_node_do_update(impl->node_proxy, - change_mask, max_input_ports, max_output_ports, NULL); + pw_client_node_proxy_update(impl->node_proxy, + change_mask, max_input_ports, max_output_ports, NULL); } static void add_port_update(struct pw_stream *stream, uint32_t change_mask) @@ -349,15 +349,15 @@ static void add_port_update(struct pw_stream *stream, uint32_t change_mask) struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); - pw_client_node_do_port_update(impl->node_proxy, - impl->direction, - impl->port_id, - change_mask, - impl->n_possible_formats, - (const struct spa_format **) impl->possible_formats, - impl->format, - impl->n_params, - (const struct spa_param **) impl->params, &impl->port_info); + pw_client_node_proxy_port_update(impl->node_proxy, + impl->direction, + impl->port_id, + change_mask, + impl->n_possible_formats, + (const struct spa_format **) impl->possible_formats, + impl->format, + impl->n_params, + (const struct spa_param **) impl->params, &impl->port_info); } static inline void send_need_input(struct pw_stream *stream) @@ -386,19 +386,19 @@ static void add_request_clock_update(struct pw_stream *stream) { struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); - pw_client_node_do_event(impl->node_proxy, (struct spa_event *) - &SPA_EVENT_NODE_REQUEST_CLOCK_UPDATE_INIT(stream->remote->core->type. - event_node. - RequestClockUpdate, - SPA_EVENT_NODE_REQUEST_CLOCK_UPDATE_TIME, - 0, 0)); + pw_client_node_proxy_event(impl->node_proxy, (struct spa_event *) + &SPA_EVENT_NODE_REQUEST_CLOCK_UPDATE_INIT(stream->remote->core->type. + event_node. + RequestClockUpdate, + SPA_EVENT_NODE_REQUEST_CLOCK_UPDATE_TIME, + 0, 0)); } static void add_async_complete(struct pw_stream *stream, uint32_t seq, int res) { struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); - pw_client_node_do_done(impl->node_proxy, seq, res); + pw_client_node_proxy_done(impl->node_proxy, seq, res); } static void do_node_init(struct pw_stream *stream) @@ -862,6 +862,7 @@ static void client_node_transport(void *object, uint32_t node_id, } static const struct pw_client_node_events client_node_events = { + PW_VERSION_CLIENT_NODE_EVENTS, &client_node_transport, &client_node_set_props, &client_node_event, @@ -913,27 +914,20 @@ pw_stream_connect(struct pw_stream *stream, if (flags & PW_STREAM_FLAG_AUTOCONNECT) pw_properties_set(stream->properties, "pipewire.autoconnect", "1"); - impl->node_proxy = pw_proxy_new(stream->remote, - SPA_ID_INVALID, - impl->type_client_node, - 0); - + impl->node_proxy = pw_core_proxy_create_node(stream->remote->core_proxy, + "client-node", + "client-node", + impl->type_client_node, + PW_VERSION_CLIENT_NODE, + &stream->properties->dict, 0, NULL); if (impl->node_proxy == NULL) return false; - pw_proxy_set_implementation(impl->node_proxy, stream, PW_VERSION_CLIENT_NODE, - &client_node_events, NULL); + pw_client_node_proxy_add_listener(impl->node_proxy, stream, &client_node_events); - pw_signal_add(&impl->node_proxy->destroy_signal, + pw_signal_add(&impl->node_proxy->proxy.destroy_signal, &impl->node_proxy_destroy, on_node_proxy_destroy); - pw_core_do_create_node(stream->remote->core_proxy, - "client-node", - "client-node", - &stream->properties->dict, - PW_VERSION_CLIENT_NODE, - impl->node_proxy->id); - do_node_init(stream); return true; @@ -972,7 +966,7 @@ void pw_stream_disconnect(struct pw_stream *stream) unhandle_socket(stream); if (impl->node_proxy) { - pw_client_node_do_destroy(impl->node_proxy); + pw_client_node_proxy_destroy(impl->node_proxy); impl->node_proxy = NULL; } } diff --git a/src/pipewire/type.c b/src/pipewire/type.c index e54df8aa1..332a6220c 100644 --- a/src/pipewire/type.c +++ b/src/pipewire/type.c @@ -39,13 +39,13 @@ void pw_type_init(struct pw_type *type) { type->map = pw_get_support_interface(SPA_TYPE__TypeMap); - type->core = spa_type_map_get_id(type->map, PW_TYPE__Core); - type->registry = spa_type_map_get_id(type->map, PW_TYPE__Registry); - type->node = spa_type_map_get_id(type->map, PW_TYPE__Node); - type->node_factory = spa_type_map_get_id(type->map, PW_TYPE__NodeFactory); - type->link = spa_type_map_get_id(type->map, PW_TYPE__Link); - type->client = spa_type_map_get_id(type->map, PW_TYPE__Client); - type->module = spa_type_map_get_id(type->map, PW_TYPE__Module); + type->core = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Core); + type->registry = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Registry); + type->node = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Node); + type->node_factory = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__NodeFactory); + type->link = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Link); + type->client = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Client); + type->module = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Module); type->spa_log = spa_type_map_get_id(type->map, SPA_TYPE__Log); type->spa_node = spa_type_map_get_id(type->map, SPA_TYPE__Node); diff --git a/src/pipewire/type.h b/src/pipewire/type.h index ac2961b46..330f8ca29 100644 --- a/src/pipewire/type.h +++ b/src/pipewire/type.h @@ -33,27 +33,13 @@ extern "C" { #include #include -#define PW_TYPE__Object "PipeWire:Object" +#define PW_TYPE_BASE "PipeWire:" + +#define PW_TYPE__Object PW_TYPE_BASE "Object" #define PW_TYPE_OBJECT_BASE PW_TYPE__Object ":" -/** \class pw_interface - * \brief The interface definition - * - * The interface implements the methods and events for a \ref - * pw_proxy. It typically implements marshal functions for the - * methods and calls the user installed implementation after - * demarshalling the events. - * - * \sa pw_proxy, pw_resource - */ -struct pw_interface { - const char *type; /**< interface type */ - uint32_t version; /**< version */ - uint32_t n_methods; /**< number of methods in the interface */ - const void *methods; /**< method implementations of the interface */ - uint32_t n_events; /**< number of events in the interface */ - const void *events; /**< event implementations of the interface */ -}; +#define PW_TYPE__Interface PW_TYPE_BASE "Interface" +#define PW_TYPE_INTERFACE_BASE PW_TYPE__Interface ":" /** \class pw_type * \brief PipeWire type support struct diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 90ebb7677..2ae60df7a 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -31,13 +31,15 @@ struct data { struct pw_loop *loop; struct pw_core *core; struct pw_remote *remote; - struct pw_proxy *registry_proxy; + struct pw_registry_proxy *registry_proxy; struct pw_listener on_info_changed; struct pw_listener on_state_changed; }; struct proxy_data { + uint32_t id; + uint32_t version; void *info; }; @@ -61,8 +63,7 @@ static void on_info_changed(struct pw_listener *listener, struct pw_remote *remo struct pw_core_info *info = remote->info; bool print_all = true, print_mark = false; - printf("\tid: %u\n", info->id); - printf("\ttype: %s\n", PW_TYPE__Core); + printf("\ttype: %s\n", PW_TYPE_INTERFACE__Core); if (print_all) { printf("%c\tuser-name: \"%s\"\n", MARK_CHANGE(0), info->user_name); printf("%c\thost-name: \"%s\"\n", MARK_CHANGE(1), info->host_name); @@ -91,8 +92,8 @@ static void module_event_info(void *object, struct pw_module_info *info) info = data->info = pw_module_info_update(data->info, info); - printf("\tid: %u\n", info->id); - printf("\ttype: %s\n", PW_TYPE__Module); + printf("\tid: %d\n", data->id); + printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Module, data->version); if (print_all) { printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); printf("%c\tfilename: \"%s\"\n", MARK_CHANGE(1), info->filename); @@ -102,6 +103,7 @@ static void module_event_info(void *object, struct pw_module_info *info) } static const struct pw_module_events module_events = { + PW_VERSION_MODULE_EVENTS, &module_event_info, }; @@ -123,8 +125,8 @@ static void node_event_info(void *object, struct pw_node_info *info) info = data->info = pw_node_info_update(data->info, info); - printf("\tid: %u\n", info->id); - printf("\ttype: %s\n", PW_TYPE__Node); + printf("\tid: %d\n", data->id); + printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Node, data->version); if (print_all) { int i; @@ -149,6 +151,7 @@ static void node_event_info(void *object, struct pw_node_info *info) } static const struct pw_node_events node_events = { + PW_VERSION_NODE_EVENTS, &node_event_info }; @@ -170,14 +173,15 @@ static void client_event_info(void *object, struct pw_client_info *info) info = data->info = pw_client_info_update(data->info, info); - printf("\tid: %u\n", info->id); - printf("\ttype: %s\n", PW_TYPE__Client); + printf("\tid: %d\n", data->id); + printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Client, data->version); if (print_all) { print_properties(info->props, MARK_CHANGE(0)); } } static const struct pw_client_events client_events = { + PW_VERSION_CLIENT_EVENTS, &client_event_info }; @@ -199,8 +203,8 @@ static void link_event_info(void *object, struct pw_link_info *info) info = data->info = pw_link_info_update(data->info, info); - printf("\tid: %u\n", info->id); - printf("\ttype: %s\n", PW_TYPE__Link); + printf("\tid: %d\n", data->id); + printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Link, data->version); if (print_all) { printf("%c\toutput-node-id: %u\n", MARK_CHANGE(0), info->output_node_id); printf("%c\toutput-port-id: %u\n", MARK_CHANGE(1), info->output_port_id); @@ -215,6 +219,7 @@ static void link_event_info(void *object, struct pw_link_info *info) } static const struct pw_link_events link_events = { + PW_VERSION_LINK_EVENTS, &link_event_info }; @@ -222,21 +227,25 @@ static void destroy_proxy (void *data) { struct pw_proxy *proxy = data; + struct pw_core *core = proxy->remote->core; struct proxy_data *user_data = proxy->user_data; - struct pw_core *core = proxy->remote->core; if (user_data->info == NULL) return; if (proxy->type == core->type.core) { pw_core_info_free (user_data->info); - } else if (proxy->type == core->type.node) { + } + else if (proxy->type == core->type.node) { pw_node_info_free (user_data->info); - } else if (proxy->type == core->type.module) { + } + else if (proxy->type == core->type.module) { pw_module_info_free (user_data->info); - } else if (proxy->type == core->type.client) { + } + else if (proxy->type == core->type.client) { pw_client_info_free (user_data->info); - } else if (proxy->type == core->type.link) { + } + else if (proxy->type == core->type.link) { pw_link_info_free (user_data->info); } user_data->info = NULL; @@ -245,39 +254,45 @@ destroy_proxy (void *data) static void registry_event_global(void *object, uint32_t id, uint32_t type, uint32_t version) { - struct pw_proxy *registry_proxy = object; - struct data *data = registry_proxy->object; - struct pw_core *core = data->core; - struct pw_remote *remote = registry_proxy->remote; - struct pw_proxy *proxy = NULL; + struct pw_proxy *proxy = object; + struct data *data = proxy->object; uint32_t client_version; - const void *implementation; + const void *events; + struct pw_core *core = data->core; + struct proxy_data *pd; - if (type == core->type.node) { - implementation = &node_events; - client_version = PW_VERSION_NODE; + if (type == core->type.node) { + events = &node_events; + client_version = PW_VERSION_NODE; } else if (type == core->type.module) { - implementation = &module_events; - client_version = PW_VERSION_MODULE; + events = &module_events; + client_version = PW_VERSION_MODULE; } else if (type == core->type.client) { - implementation = &client_events; - client_version = PW_VERSION_CLIENT; + events = &client_events; + client_version = PW_VERSION_CLIENT; } else if (type == core->type.link) { - implementation = &link_events; - client_version = PW_VERSION_LINK; - } else - return; + events = &link_events; + client_version = PW_VERSION_LINK; + } + else { + printf("added:\n"); + printf("\tid: %u\n", id); + printf("\ttype: %s (version %d)\n", spa_type_map_get_type(core->type.map, type), version); + return; + } - proxy = pw_proxy_new(remote, SPA_ID_INVALID, type, sizeof(struct proxy_data)); + proxy = pw_registry_proxy_bind(data->registry_proxy, id, type, + client_version, sizeof(struct proxy_data), destroy_proxy); if (proxy == NULL) goto no_mem; - pw_proxy_set_implementation(proxy, data, client_version, implementation, destroy_proxy); - - pw_registry_do_bind(registry_proxy, id, version, proxy->id); + pd = proxy->user_data; + pd->id = id; + pd->version = version; + pw_proxy_add_listener(proxy, proxy, events); return; @@ -293,6 +308,7 @@ static void registry_event_global_remove(void *object, uint32_t id) } static const struct pw_registry_events registry_events = { + PW_VERSION_REGISTRY_EVENTS, registry_event_global, registry_event_global_remove, }; @@ -310,16 +326,10 @@ static void on_state_changed(struct pw_listener *listener, struct pw_remote *rem case PW_REMOTE_STATE_CONNECTED: printf("remote state: \"%s\"\n", pw_remote_state_as_string(remote->state)); - data->registry_proxy = pw_proxy_new(data->remote, - SPA_ID_INVALID, - data->core->type.registry, - 0); - pw_proxy_set_implementation(data->registry_proxy, data, PW_VERSION_REGISTRY, - ®istry_events, NULL); - - pw_core_do_get_registry(data->remote->core_proxy, PW_VERSION_REGISTRY, - data->registry_proxy->id); - + data->registry_proxy = pw_core_proxy_get_registry(data->remote->core_proxy, + PW_VERSION_REGISTRY, 0, NULL); + pw_registry_proxy_add_listener(data->registry_proxy, + data, ®istry_events); break; default: