diff --git a/src/examples/local-v4l2.c b/src/examples/local-v4l2.c index 5dc3569c0..9c7d5d855 100644 --- a/src/examples/local-v4l2.c +++ b/src/examples/local-v4l2.c @@ -464,7 +464,7 @@ static void make_nodes(struct data *data) struct pw_node_factory *factory; struct pw_properties *props; - data->node = pw_node_new(data->core, NULL, "SDL-sink", NULL, 0); + data->node = pw_node_new(data->core, NULL, NULL, "SDL-sink", NULL, 0); data->node->user_data = data; data->node->implementation = &impl_node; @@ -480,6 +480,7 @@ static void make_nodes(struct data *data) data->v4l2 = pw_node_factory_create_node(factory, NULL, "v4l2-source", props); data->link = pw_link_new(data->core, + NULL, pw_node_get_free_port(data->v4l2, PW_DIRECTION_OUTPUT), data->port, NULL, diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index d9c8111c8..fe62e8f9a 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -303,6 +303,7 @@ on_sync_reply (struct pw_listener *listener, struct pw_remote *remote, uint32_t struct node_data { GstPipeWireDeviceProvider *self; uint32_t id; + uint32_t parent_id; }; static void node_event_info(void *object, struct pw_node_info *info) @@ -327,7 +328,8 @@ static const struct pw_node_events node_events = { }; -static void registry_event_global(void *object, uint32_t id, uint32_t type, uint32_t version) +static void registry_event_global(void *object, uint32_t id, uint32_t parent_id, + uint32_t type, uint32_t version) { struct pw_registry_proxy *registry = object; GstPipeWireDeviceProvider *self = registry->proxy.user_data; @@ -346,6 +348,7 @@ static void registry_event_global(void *object, uint32_t id, uint32_t type, uint data = node->proxy.user_data; data->id = id; + data->parent_id = parent_id; data->self = self; pw_node_proxy_add_listener(node, node, &node_events); return; diff --git a/src/modules/module-autolink.c b/src/modules/module-autolink.c index ea1234b80..95ef95832 100644 --- a/src/modules/module-autolink.c +++ b/src/modules/module-autolink.c @@ -29,6 +29,7 @@ struct impl { struct pw_core *core; + struct pw_module *module; struct pw_properties *properties; struct pw_listener global_added; @@ -176,9 +177,9 @@ static void try_link_port(struct pw_node *node, struct pw_port *port, struct nod goto error; if (port->direction == PW_DIRECTION_OUTPUT) - link = pw_link_new(impl->core, port, target, NULL, NULL, &error); + link = pw_link_new(impl->core, impl->module->global, port, target, NULL, NULL, &error); else - link = pw_link_new(impl->core, target, port, NULL, NULL, &error); + link = pw_link_new(impl->core, impl->module->global, target, port, NULL, NULL, &error); if (link == NULL) goto error; @@ -287,14 +288,16 @@ on_global_removed(struct pw_listener *listener, struct pw_core *core, struct pw_ * * Returns: a new #struct impl */ -static struct impl *module_new(struct pw_core *core, struct pw_properties *properties) +static bool module_init(struct pw_module *module, struct pw_properties *properties) { + struct pw_core *core = module->core; struct impl *impl; impl = calloc(1, sizeof(struct impl)); pw_log_debug("module %p: new", impl); impl->core = core; + impl->module = module; impl->properties = properties; spa_list_init(&impl->node_list); @@ -324,6 +327,5 @@ static void module_destroy(struct impl *impl) bool pipewire__module_init(struct pw_module *module, const char *args) { - module->user_data = module_new(module->core, NULL); - return true; + return module_init(module, NULL); } diff --git a/src/modules/module-client-node.c b/src/modules/module-client-node.c index d780d2f51..571f771aa 100644 --- a/src/modules/module-client-node.c +++ b/src/modules/module-client-node.c @@ -67,11 +67,15 @@ static struct pw_node *create_node(struct pw_node_factory *factory, return NULL; } -static struct impl *module_new(struct pw_core *core, struct pw_properties *properties) +static bool module_init(struct pw_module *module, struct pw_properties *properties) { + struct pw_core *core = module->core; struct impl *impl; impl = calloc(1, sizeof(struct impl)); + if (impl == NULL) + return false; + pw_log_debug("module %p: new", impl); impl->properties = properties; @@ -86,10 +90,11 @@ 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, - NULL, impl, &impl->this.global); + impl->this.global = pw_core_add_global(core, NULL, module->global, + core->type.node_factory, 0, + NULL, impl); - return impl; + return true; } #if 0 @@ -103,6 +108,5 @@ static void module_destroy(struct impl *impl) bool pipewire__module_init(struct pw_module *module, const char *args) { - module_new(module->core, NULL); - return true; + return module_init(module, NULL); } diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 8d6ca810d..ea6266401 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -122,7 +122,6 @@ struct impl { struct pw_listener node_free; struct pw_listener initialized; - struct pw_listener global_added; int fds[2]; int other_fds[2]; @@ -1056,15 +1055,6 @@ static void on_initialized(struct pw_listener *listener, struct pw_node *node) readfd, writefd, info.memfd, info.offset, info.size); } -static void -on_global_added(struct pw_listener *listener, struct pw_core *core, struct pw_global *global) -{ - struct impl *impl = SPA_CONTAINER_OF(listener, struct impl, global_added); - - if (global->object == impl->this.node) - global->owner = impl->this.resource; -} - static int proxy_clear(struct proxy *this) { uint32_t i; @@ -1092,7 +1082,6 @@ static void client_node_resource_destroy(struct pw_resource *resource) impl->proxy.resource = this->resource = NULL; - pw_signal_remove(&impl->global_added); pw_signal_remove(&impl->initialized); if (proxy->data_source.fd != -1) @@ -1157,6 +1146,7 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource, this->resource = resource; this->node = pw_spa_node_new(core, this->resource, + NULL, name, true, &impl->proxy.node, @@ -1173,7 +1163,6 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource, pw_signal_add(&this->node->free_signal, &impl->node_free, on_node_free); pw_signal_add(&this->node->initialized, &impl->initialized, on_initialized); - pw_signal_add(&impl->core->global_added, &impl->global_added, on_global_added); return this; diff --git a/src/modules/module-jack.c b/src/modules/module-jack.c index 49100beb5..41762d13e 100644 --- a/src/modules/module-jack.c +++ b/src/modules/module-jack.c @@ -78,6 +78,7 @@ struct socket { struct impl { struct pw_core *core; + struct pw_module *module; struct spa_list link; struct pw_properties *properties; @@ -444,7 +445,7 @@ static struct client *client_new(struct impl *impl, int fd) ucredp = &ucred; } - client = pw_client_new(impl->core, ucredp, NULL, sizeof(struct client)); + client = pw_client_new(impl->core, impl->module->global, ucredp, NULL, sizeof(struct client)); if (client == NULL) goto no_client; @@ -695,8 +696,9 @@ static int init_server(struct impl *impl, const char *name, bool promiscuous) } -static struct impl *module_new(struct pw_core *core, struct pw_properties *properties) +static struct impl *module_init(struct pw_module *module, struct pw_properties *properties) { + struct pw_core *core = module->core; struct impl *impl; const char *name, *str; bool promiscuous; @@ -705,6 +707,7 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope pw_log_debug("protocol-jack %p: new", impl); impl->core = core; + impl->module = module; impl->properties = properties; spa_list_init(&impl->socket_list); @@ -749,6 +752,6 @@ static void module_destroy(struct impl *impl) bool pipewire__module_init(struct pw_module *module, const char *args) { - module_new(module->core, NULL); + module_init(module, NULL); return true; } diff --git a/src/modules/module-mixer.c b/src/modules/module-mixer.c index 6812c2f5a..dad580fe7 100644 --- a/src/modules/module-mixer.c +++ b/src/modules/module-mixer.c @@ -32,6 +32,7 @@ struct impl { struct pw_core *core; + struct pw_module *module; struct pw_properties *properties; void *hnd; @@ -109,7 +110,8 @@ static struct pw_node *make_node(struct impl *impl) } spa_clock = iface; - node = pw_spa_node_new(impl->core, NULL, "audiomixer", false, spa_node, spa_clock, NULL); + node = pw_spa_node_new(impl->core, NULL, impl->module->global, + "audiomixer", false, spa_node, spa_clock, NULL); return node; @@ -120,8 +122,9 @@ static struct pw_node *make_node(struct impl *impl) return NULL; } -static struct impl *module_new(struct pw_core *core, struct pw_properties *properties) +static bool module_init(struct pw_module *module, struct pw_properties *properties) { + struct pw_core *core = module->core; struct impl *impl; struct pw_node *n; @@ -129,6 +132,7 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope pw_log_debug("module %p: new", impl); impl->core = core; + impl->module = module; impl->properties = properties; impl->factory = find_factory(impl); @@ -162,7 +166,7 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope n->idle_used_input_links++; node->idle_used_output_links++; - pw_link_new(core, op, ip, NULL, NULL, &error); + pw_link_new(core, module->global, op, ip, NULL, NULL, &error); } return impl; } @@ -178,6 +182,5 @@ static void module_destroy(struct impl *impl) bool pipewire__module_init(struct pw_module *module, const char *args) { - module_new(module->core, NULL); - return true; + return module_init(module, NULL); } diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index a36a67eaf..4331aca35 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -56,6 +56,10 @@ void pw_protocol_native_init(struct pw_protocol *protocol); typedef bool(*demarshal_func_t) (void *object, void *data, size_t size); +struct protocol_data { + struct pw_module *module; +}; + struct connection { struct pw_protocol_connection this; @@ -82,10 +86,6 @@ struct listener { struct spa_loop_control_hooks hooks; }; -struct protocol_data { - void *unused; -}; - struct client_data { int fd; struct spa_source *source; @@ -198,6 +198,7 @@ static struct pw_client *client_new(struct listener *l, int fd) struct client_data *this; struct pw_client *client; struct pw_protocol *protocol = l->this.protocol; + struct protocol_data *pd = protocol->user_data; socklen_t len; struct ucred ucred, *ucredp; @@ -209,7 +210,7 @@ static struct pw_client *client_new(struct listener *l, int fd) ucredp = &ucred; } - client = pw_client_new(protocol->core, ucredp, NULL, sizeof(struct client_data)); + client = pw_client_new(protocol->core, pd->module->global, ucredp, NULL, sizeof(struct client_data)); if (client == NULL) goto no_client; @@ -698,14 +699,16 @@ const static struct pw_protocol_native_ext protocol_ext_impl = { impl_ext_end_resource, }; -static struct pw_protocol *pw_protocol_native_new(struct pw_core *core, struct pw_properties *properties) +static bool module_init(struct pw_module *module, struct pw_properties *properties) { + struct pw_core *core = module->core; struct pw_protocol *this; const char *val; + struct protocol_data *d; this = pw_protocol_new(core, PW_TYPE_PROTOCOL__Native, sizeof(struct protocol_data)); if (this == NULL) - return NULL; + return false; this->implementation = &protocol_impl; this->extension = &protocol_ext_impl; @@ -714,11 +717,14 @@ static struct pw_protocol *pw_protocol_native_new(struct pw_core *core, struct p pw_log_debug("protocol-native %p: new", this); + d = this->user_data; + d->module = module; + if ((val = pw_properties_get(core->properties, "pipewire.daemon"))) { if (atoi(val) == 1) impl_add_listener(this, core, properties); } - return this; + return true; } #if 0 @@ -741,6 +747,5 @@ static void pw_protocol_native_destroy(struct impl *impl) bool pipewire__module_init(struct pw_module *module, const char *args) { - pw_protocol_native_new(module->core, NULL); - return true; + return module_init(module, NULL); } diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index c0ada9ce9..594a1492c 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -529,7 +529,8 @@ static bool core_demarshal_update_types_server(void *object, void *data, size_t return true; } -static void registry_marshal_global(void *object, uint32_t id, uint32_t type, uint32_t version) +static void registry_marshal_global(void *object, uint32_t id, uint32_t parent_id, + uint32_t type, uint32_t version) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -539,6 +540,7 @@ static void registry_marshal_global(void *object, uint32_t id, uint32_t type, ui spa_pod_builder_struct(b, &f, SPA_POD_TYPE_INT, id, + SPA_POD_TYPE_INT, parent_id, SPA_POD_TYPE_ID, type, SPA_POD_TYPE_INT, version); @@ -742,7 +744,8 @@ 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_LONG, info->change_mask, SPA_POD_TYPE_INT, n_items, 0); + SPA_POD_TYPE_LONG, info->change_mask, + SPA_POD_TYPE_INT, n_items, 0); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, @@ -824,17 +827,18 @@ static bool registry_demarshal_global(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_pod_iter it; - uint32_t id, type, version; + uint32_t id, parent_id, type, version; 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, &id, + SPA_POD_TYPE_INT, &parent_id, SPA_POD_TYPE_ID, &type, SPA_POD_TYPE_INT, &version, 0)) return false; - pw_proxy_notify(proxy, struct pw_registry_events, global, id, type, version); + pw_proxy_notify(proxy, struct pw_registry_events, global, id, parent_id, type, version); return true; } diff --git a/src/modules/spa/module-monitor.c b/src/modules/spa/module-monitor.c index f3f2b2480..31d3bb853 100644 --- a/src/modules/spa/module-monitor.c +++ b/src/modules/spa/module-monitor.c @@ -49,7 +49,7 @@ bool pipewire__module_init(struct pw_module *module, const char *args) if ((dir = getenv("SPA_PLUGIN_DIR")) == NULL) dir = PLUGINDIR; - pw_spa_monitor_load(module->core, dir, argv[0], argv[1], argv[2]); + pw_spa_monitor_load(module->core, module->global, dir, argv[0], argv[1], argv[2]); pw_free_strv(argv); diff --git a/src/modules/spa/module-node-factory.c b/src/modules/spa/module-node-factory.c index 6b6718f29..fbf5990ff 100644 --- a/src/modules/spa/module-node-factory.c +++ b/src/modules/spa/module-node-factory.c @@ -53,6 +53,7 @@ static struct pw_node *create_node(struct pw_node_factory *factory, goto no_properties; node = pw_spa_node_load(factory->core, + NULL, NULL, lib, factory_name, @@ -81,11 +82,15 @@ static struct pw_node *create_node(struct pw_node_factory *factory, return NULL; } -static struct impl *module_new(struct pw_core *core, struct pw_properties *properties) +static bool module_init(struct pw_module *module, struct pw_properties *properties) { + struct pw_core *core = module->core; struct impl *impl; impl = calloc(1, sizeof(struct impl)); + if (impl == NULL) + return false; + pw_log_debug("module %p: new", impl); impl->properties = properties; @@ -97,10 +102,10 @@ 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, - NULL, impl, &impl->this.global); + impl->this.global = pw_core_add_global(core, NULL, module->global, core->type.node_factory, 0, + NULL, impl); - return impl; + return true; } #if 0 @@ -114,6 +119,5 @@ static void module_destroy(struct impl *impl) bool pipewire__module_init(struct pw_module *module, const char *args) { - module_new(module->core, NULL); - return true; + return module_init(module, NULL); } diff --git a/src/modules/spa/module-node.c b/src/modules/spa/module-node.c index d44fd1ba5..95737ff49 100644 --- a/src/modules/spa/module-node.c +++ b/src/modules/spa/module-node.c @@ -60,7 +60,7 @@ bool pipewire__module_init(struct pw_module *module, const char *args) pw_free_strv(prop); } - pw_spa_node_load(module->core, NULL, argv[0], argv[1], argv[2], props); + pw_spa_node_load(module->core, NULL, module->global, argv[0], argv[1], argv[2], props); pw_free_strv(argv); diff --git a/src/modules/spa/spa-monitor.c b/src/modules/spa/spa-monitor.c index d037b1715..88fc2919e 100644 --- a/src/modules/spa/spa-monitor.c +++ b/src/modules/spa/spa-monitor.c @@ -47,6 +47,7 @@ struct impl { struct pw_spa_monitor this; struct pw_core *core; + struct pw_global *parent; void *hnd; @@ -110,7 +111,8 @@ static void add_item(struct pw_spa_monitor *this, struct spa_monitor_item *item) mitem = calloc(1, sizeof(struct monitor_item)); mitem->id = strdup(id); - mitem->node = pw_spa_node_new(impl->core, NULL, name, false, node_iface, clock_iface, props); + mitem->node = pw_spa_node_new(impl->core, NULL, impl->parent, name, + false, node_iface, clock_iface, props); spa_list_insert(impl->item_list.prev, &mitem->link); } @@ -203,6 +205,7 @@ static const struct spa_monitor_callbacks callbacks = { }; struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core, + struct pw_global *parent, const char *dir, const char *lib, const char *factory_name, const char *system_name) @@ -252,6 +255,7 @@ struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core, impl = calloc(1, sizeof(struct impl)); impl->core = core; + impl->parent = parent; impl->hnd = hnd; this = &impl->this; diff --git a/src/modules/spa/spa-monitor.h b/src/modules/spa/spa-monitor.h index 846d16fcc..bab4b686e 100644 --- a/src/modules/spa/spa-monitor.h +++ b/src/modules/spa/spa-monitor.h @@ -41,6 +41,7 @@ struct pw_spa_monitor { struct pw_spa_monitor * pw_spa_monitor_load(struct pw_core *core, + struct pw_global *parent, const char *dir, const char *lib, const char *factory_name, const char *system_name); diff --git a/src/modules/spa/spa-node.c b/src/modules/spa/spa-node.c index a3aaf5c1a..680ab6ed0 100644 --- a/src/modules/spa/spa-node.c +++ b/src/modules/spa/spa-node.c @@ -387,6 +387,7 @@ static const struct spa_node_callbacks node_callbacks = { struct pw_node * pw_spa_node_new(struct pw_core *core, struct pw_resource *owner, + struct pw_global *parent, const char *name, bool async, struct spa_node *node, @@ -411,7 +412,7 @@ pw_spa_node_new(struct pw_core *core, node->info->items[i].value); } - this = pw_node_new(core, owner, name, properties, sizeof(struct impl)); + this = pw_node_new(core, owner, parent, name, properties, sizeof(struct impl)); if (this == NULL) return NULL; @@ -498,6 +499,7 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie struct pw_node *pw_spa_node_load(struct pw_core *core, struct pw_resource *owner, + struct pw_global *parent, const char *lib, const char *factory_name, const char *name, @@ -567,7 +569,7 @@ struct pw_node *pw_spa_node_load(struct pw_core *core, } } - this = pw_spa_node_new(core, owner, name, async, spa_node, spa_clock, properties); + this = pw_spa_node_new(core, owner, parent, name, async, spa_node, spa_clock, properties); impl->hnd = hnd; impl->handle = handle; impl->lib = filename; diff --git a/src/modules/spa/spa-node.h b/src/modules/spa/spa-node.h index 35eba6a2f..b39a1966a 100644 --- a/src/modules/spa/spa-node.h +++ b/src/modules/spa/spa-node.h @@ -30,6 +30,7 @@ extern "C" { struct pw_node * pw_spa_node_new(struct pw_core *core, struct pw_resource *owner, /**< optional owner */ + struct pw_global *parent, /**< optional parent */ const char *name, bool async, struct spa_node *node, @@ -39,6 +40,7 @@ pw_spa_node_new(struct pw_core *core, struct pw_node * pw_spa_node_load(struct pw_core *core, struct pw_resource *owner, /**< optional owner */ + struct pw_global *parent, /**< optional parent */ const char *lib, const char *factory_name, const char *name, diff --git a/src/pipewire/client.c b/src/pipewire/client.c index a2734ba6e..b72582146 100644 --- a/src/pipewire/client.c +++ b/src/pipewire/client.c @@ -78,6 +78,7 @@ client_bind_func(struct pw_global *global, * \memberof pw_client */ struct pw_client *pw_client_new(struct pw_core *core, + struct pw_global *parent, struct ucred *ucred, struct pw_properties *properties, size_t user_data_size) @@ -113,11 +114,11 @@ 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, - client_bind_func, this, &this->global); - this->info.props = this->properties ? &this->properties->dict : NULL; + this->global = pw_core_add_global(core, NULL, parent, core->type.client, PW_VERSION_CLIENT, + client_bind_func, this); + return this; } diff --git a/src/pipewire/client.h b/src/pipewire/client.h index 0d6827ad0..3451329c3 100644 --- a/src/pipewire/client.h +++ b/src/pipewire/client.h @@ -127,6 +127,7 @@ struct pw_client { struct pw_client * pw_client_new(struct pw_core *core, + struct pw_global *parent, struct ucred *ucred, struct pw_properties *properties, size_t user_data_size); diff --git a/src/pipewire/core.c b/src/pipewire/core.c index c5dc15812..75c10c64d 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -69,7 +69,6 @@ static void registry_bind(void *object, uint32_t id, struct pw_client *client = resource->client; struct pw_core *core = resource->core; struct pw_global *global; - const char *type_name; if ((global = find_global(core, id)) == 0) goto no_id; @@ -80,9 +79,8 @@ static void registry_bind(void *object, uint32_t 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 global id %d, iface %s to %d", global, id, + spa_type_map_get_type(core->type.map, type), new_id); pw_global_bind(global, client, version, new_id); @@ -154,6 +152,7 @@ static void core_get_registry(void *object, uint32_t version, uint32_t new_id) if (pw_global_is_visible(global, client)) { pw_registry_resource_global(registry_resource, global->id, + global->parent->id, global->type, global->version); } @@ -359,9 +358,6 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro pw_signal_init(&this->global_added); pw_signal_init(&this->global_removed); - pw_core_add_global(this, NULL, this->type.core, PW_VERSION_CORE, - core_bind_func, this, &this->global); - this->info.change_mask = 0; this->info.user_name = pw_get_user_name(); this->info.host_name = pw_get_host_name(); @@ -380,6 +376,9 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro this->info.name = pw_properties_get(properties, "pipewire.core.name"); this->properties = properties; + this->global = pw_core_add_global(this, NULL, NULL, this->type.core, PW_VERSION_CORE, + core_bind_func, this); + return this; no_data_loop: @@ -422,23 +421,22 @@ void pw_core_destroy(struct pw_core *core) * * \memberof pw_core */ -bool +struct pw_global * pw_core_add_global(struct pw_core *core, struct pw_resource *owner, + struct pw_global *parent, uint32_t type, uint32_t version, pw_bind_func_t bind, - void *object, - struct pw_global **global) + void *object) { 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; + return NULL; this = &impl->this; @@ -448,24 +446,31 @@ pw_core_add_global(struct pw_core *core, this->version = version; this->bind = bind; this->object = object; - *global = this; pw_signal_init(&this->destroy_signal); this->id = pw_map_insert_new(&core->objects, this); + if (owner && owner->client) + parent = owner->client->global; + if (parent == NULL) + parent = core->global; + if (parent == NULL) + parent = this; + this->parent = parent; + spa_list_insert(core->global_list.prev, &this->link); pw_signal_emit(&core->global_added, core, this); - 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); + pw_log_debug("global %p: new %u %s, owner %p", this, this->id, + spa_type_map_get_type(core->type.map, this->type), owner); spa_list_for_each(registry, &core->registry_resource_list, link) if (pw_global_is_visible(this, registry->client)) - pw_registry_resource_global(registry, this->id, this->type, this->version); + pw_registry_resource_global(registry, this->id, this->parent->id, + this->type, this->version); - return true; + return this; } /** Bind to a global diff --git a/src/pipewire/core.h b/src/pipewire/core.h index 94dd1b83e..c934c0481 100644 --- a/src/pipewire/core.h +++ b/src/pipewire/core.h @@ -127,6 +127,7 @@ struct pw_global { struct spa_list link; /**< link in core list of globals */ uint32_t id; /**< server id of the object */ + struct pw_global *parent; /**< parent global */ uint32_t type; /**< type of interface */ uint32_t version; /**< version of interface */ @@ -204,14 +205,14 @@ pw_core_destroy(struct pw_core *core); void pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict); -bool +struct pw_global * pw_core_add_global(struct pw_core *core, struct pw_resource *owner, + struct pw_global *parent, uint32_t type, uint32_t version, pw_bind_func_t bind, - void *object, - struct pw_global **global); + void *object); int pw_global_bind(struct pw_global *global, diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h index 8c5220aaa..634b2fd8b 100644 --- a/src/pipewire/interfaces.h +++ b/src/pipewire/interfaces.h @@ -364,10 +364,11 @@ struct pw_registry_events { * available. * * \param id the global object id + * \param parent_id the parent global id * \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); + void (*global) (void *object, uint32_t id, uint32_t parent_id, uint32_t type, uint32_t version); /** * Notify of a global object removal * diff --git a/src/pipewire/link.c b/src/pipewire/link.c index d69f96c2a..c3ea9e5a7 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -987,6 +987,7 @@ do_add_link(struct spa_loop *loop, } struct pw_link *pw_link_new(struct pw_core *core, + struct pw_global *parent, struct pw_port *output, struct pw_port *input, struct spa_format *format_filter, @@ -1056,9 +1057,6 @@ 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, - link_bind_func, this, &this->global); - 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; @@ -1083,6 +1081,9 @@ struct pw_link *pw_link_new(struct pw_core *core, do_add_link, SPA_ID_INVALID, sizeof(struct pw_port *), &input, false, this); + this->global = pw_core_add_global(core, NULL, parent, core->type.link, PW_VERSION_LINK, + link_bind_func, this); + return this; same_ports: diff --git a/src/pipewire/link.h b/src/pipewire/link.h index dbd6e564b..791edda02 100644 --- a/src/pipewire/link.h +++ b/src/pipewire/link.h @@ -95,6 +95,7 @@ struct pw_link { * \return a newly allocated link */ struct pw_link * pw_link_new(struct pw_core *core, /**< the core object */ + struct pw_global *parent, /**< parent global */ struct pw_port *output, /**< an output port */ struct pw_port *input, /**< an input port */ struct spa_format *format_filter, /**< an optional format filter */ diff --git a/src/pipewire/module.c b/src/pipewire/module.c index d7c2af1a9..45b1a06db 100644 --- a/src/pipewire/module.c +++ b/src/pipewire/module.c @@ -180,17 +180,18 @@ struct pw_module *pw_module_load(struct pw_core *core, pw_signal_init(&this->destroy_signal); - if (!init_func(this, (char *) args)) - goto init_failed; - - pw_core_add_global(core, NULL, core->type.module, PW_VERSION_MODULE, - module_bind_func, this, &this->global); - this->info.name = name ? strdup(name) : NULL; this->info.filename = filename; this->info.args = args ? strdup(args) : NULL; this->info.props = NULL; + this->global = pw_core_add_global(core, NULL, core->global, + core->type.module, PW_VERSION_MODULE, + module_bind_func, this); + + if (!init_func(this, (char *) args)) + goto init_failed; + pw_log_debug("loaded module: %s", this->info.name); return this; diff --git a/src/pipewire/node.c b/src/pipewire/node.c index bfd6e1605..ac9724f8f 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -34,6 +34,8 @@ struct impl { struct pw_node this; + struct pw_global *parent; + struct pw_work_queue *work; struct pw_listener on_async_complete; struct pw_listener on_event; @@ -255,20 +257,20 @@ do_node_add(struct spa_loop *loop, void pw_node_export(struct pw_node *this) { struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); + struct pw_core *core = this->core; pw_log_debug("node %p: export", 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, - node_bind_func, this, &this->global); + update_info(this); pw_loop_invoke(this->data_loop, do_node_add, 1, 0, NULL, false, this); - update_info(this); + spa_list_insert(core->node_list.prev, &this->link); + this->global = pw_core_add_global(core, this->owner, impl->parent, + core->type.node, PW_VERSION_NODE, + node_bind_func, this); impl->exported = true; - pw_signal_emit(&this->initialized, this); pw_node_update_state(this, PW_NODE_STATE_SUSPENDED, NULL); @@ -296,6 +298,7 @@ static const struct spa_graph_node_methods graph_methods = { struct pw_node *pw_node_new(struct pw_core *core, struct pw_resource *owner, + struct pw_global *parent, const char *name, struct pw_properties *properties, size_t user_data_size) @@ -316,6 +319,7 @@ struct pw_node *pw_node_new(struct pw_core *core, this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void); impl->work = pw_work_queue_new(this->core->main_loop); + impl->parent = parent; this->info.name = strdup(name); this->properties = properties; diff --git a/src/pipewire/node.h b/src/pipewire/node.h index 20e3b9c1f..c97b6de27 100644 --- a/src/pipewire/node.h +++ b/src/pipewire/node.h @@ -148,6 +148,7 @@ struct pw_node { struct pw_node * pw_node_new(struct pw_core *core, /**< the core */ struct pw_resource *owner, /**< optional owner */ + struct pw_global *parent, /**< optional parent */ const char *name, /**< node name */ struct pw_properties *properties, /**< extra properties */ size_t user_data_size /**< user data size */); diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 2ae60df7a..c9b8d36da 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -39,6 +39,7 @@ struct data { struct proxy_data { uint32_t id; + uint32_t parent_id; uint32_t version; void *info; }; @@ -93,6 +94,7 @@ static void module_event_info(void *object, struct pw_module_info *info) info = data->info = pw_module_info_update(data->info, info); printf("\tid: %d\n", data->id); + printf("\tparent_id: %d\n", data->parent_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); @@ -126,6 +128,7 @@ static void node_event_info(void *object, struct pw_node_info *info) info = data->info = pw_node_info_update(data->info, info); printf("\tid: %d\n", data->id); + printf("\tparent_id: %d\n", data->parent_id); printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Node, data->version); if (print_all) { int i; @@ -174,6 +177,7 @@ static void client_event_info(void *object, struct pw_client_info *info) info = data->info = pw_client_info_update(data->info, info); printf("\tid: %d\n", data->id); + printf("\tparent_id: %d\n", data->parent_id); printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Client, data->version); if (print_all) { print_properties(info->props, MARK_CHANGE(0)); @@ -204,6 +208,7 @@ static void link_event_info(void *object, struct pw_link_info *info) info = data->info = pw_link_info_update(data->info, info); printf("\tid: %d\n", data->id); + printf("\tparent_id: %d\n", data->parent_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); @@ -252,7 +257,8 @@ destroy_proxy (void *data) } -static void registry_event_global(void *object, uint32_t id, uint32_t type, uint32_t version) +static void registry_event_global(void *object, uint32_t id, uint32_t parent_id, + uint32_t type, uint32_t version) { struct pw_proxy *proxy = object; struct data *data = proxy->object; @@ -280,6 +286,7 @@ static void registry_event_global(void *object, uint32_t id, uint32_t type, uint else { printf("added:\n"); printf("\tid: %u\n", id); + printf("\tparent_id: %d\n", parent_id); printf("\ttype: %s (version %d)\n", spa_type_map_get_type(core->type.map, type), version); return; } @@ -291,6 +298,7 @@ static void registry_event_global(void *object, uint32_t id, uint32_t type, uint pd = proxy->user_data; pd->id = id; + pd->parent_id = parent_id; pd->version = version; pw_proxy_add_listener(proxy, proxy, events);