Add parent_id

Add parent_id to globals to make hierarchy of interfaces. We can use
this to group interfaces or to describe the owner.
This commit is contained in:
Wim Taymans 2017-07-18 14:58:14 +02:00
parent 1acba78234
commit a003d1a39f
27 changed files with 151 additions and 99 deletions

View file

@ -464,7 +464,7 @@ static void make_nodes(struct data *data)
struct pw_node_factory *factory; struct pw_node_factory *factory;
struct pw_properties *props; 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->user_data = data;
data->node->implementation = &impl_node; 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->v4l2 = pw_node_factory_create_node(factory, NULL, "v4l2-source", props);
data->link = pw_link_new(data->core, data->link = pw_link_new(data->core,
NULL,
pw_node_get_free_port(data->v4l2, PW_DIRECTION_OUTPUT), pw_node_get_free_port(data->v4l2, PW_DIRECTION_OUTPUT),
data->port, data->port,
NULL, NULL,

View file

@ -303,6 +303,7 @@ on_sync_reply (struct pw_listener *listener, struct pw_remote *remote, uint32_t
struct node_data { struct node_data {
GstPipeWireDeviceProvider *self; GstPipeWireDeviceProvider *self;
uint32_t id; uint32_t id;
uint32_t parent_id;
}; };
static void node_event_info(void *object, struct pw_node_info *info) 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; struct pw_registry_proxy *registry = object;
GstPipeWireDeviceProvider *self = registry->proxy.user_data; 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 = node->proxy.user_data;
data->id = id; data->id = id;
data->parent_id = parent_id;
data->self = self; data->self = self;
pw_node_proxy_add_listener(node, node, &node_events); pw_node_proxy_add_listener(node, node, &node_events);
return; return;

View file

@ -29,6 +29,7 @@
struct impl { struct impl {
struct pw_core *core; struct pw_core *core;
struct pw_module *module;
struct pw_properties *properties; struct pw_properties *properties;
struct pw_listener global_added; 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; goto error;
if (port->direction == PW_DIRECTION_OUTPUT) 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 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) if (link == NULL)
goto error; goto error;
@ -287,14 +288,16 @@ on_global_removed(struct pw_listener *listener, struct pw_core *core, struct pw_
* *
* Returns: a new #struct impl * 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; struct impl *impl;
impl = calloc(1, sizeof(struct impl)); impl = calloc(1, sizeof(struct impl));
pw_log_debug("module %p: new", impl); pw_log_debug("module %p: new", impl);
impl->core = core; impl->core = core;
impl->module = module;
impl->properties = properties; impl->properties = properties;
spa_list_init(&impl->node_list); 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) bool pipewire__module_init(struct pw_module *module, const char *args)
{ {
module->user_data = module_new(module->core, NULL); return module_init(module, NULL);
return true;
} }

View file

@ -67,11 +67,15 @@ static struct pw_node *create_node(struct pw_node_factory *factory,
return NULL; 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 impl *impl;
impl = calloc(1, sizeof(struct impl)); impl = calloc(1, sizeof(struct impl));
if (impl == NULL)
return false;
pw_log_debug("module %p: new", impl); pw_log_debug("module %p: new", impl);
impl->properties = properties; 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); spa_list_insert(core->node_factory_list.prev, &impl->this.link);
pw_core_add_global(core, NULL, core->type.node_factory, 0, impl->this.global = pw_core_add_global(core, NULL, module->global,
NULL, impl, &impl->this.global); core->type.node_factory, 0,
NULL, impl);
return impl; return true;
} }
#if 0 #if 0
@ -103,6 +108,5 @@ static void module_destroy(struct impl *impl)
bool pipewire__module_init(struct pw_module *module, const char *args) bool pipewire__module_init(struct pw_module *module, const char *args)
{ {
module_new(module->core, NULL); return module_init(module, NULL);
return true;
} }

View file

@ -122,7 +122,6 @@ struct impl {
struct pw_listener node_free; struct pw_listener node_free;
struct pw_listener initialized; struct pw_listener initialized;
struct pw_listener global_added;
int fds[2]; int fds[2];
int other_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); 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) static int proxy_clear(struct proxy *this)
{ {
uint32_t i; uint32_t i;
@ -1092,7 +1082,6 @@ static void client_node_resource_destroy(struct pw_resource *resource)
impl->proxy.resource = this->resource = NULL; impl->proxy.resource = this->resource = NULL;
pw_signal_remove(&impl->global_added);
pw_signal_remove(&impl->initialized); pw_signal_remove(&impl->initialized);
if (proxy->data_source.fd != -1) 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->resource = resource;
this->node = pw_spa_node_new(core, this->node = pw_spa_node_new(core,
this->resource, this->resource,
NULL,
name, name,
true, true,
&impl->proxy.node, &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->free_signal, &impl->node_free, on_node_free);
pw_signal_add(&this->node->initialized, &impl->initialized, on_initialized); 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; return this;

View file

@ -78,6 +78,7 @@ struct socket {
struct impl { struct impl {
struct pw_core *core; struct pw_core *core;
struct pw_module *module;
struct spa_list link; struct spa_list link;
struct pw_properties *properties; struct pw_properties *properties;
@ -444,7 +445,7 @@ static struct client *client_new(struct impl *impl, int fd)
ucredp = &ucred; 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) if (client == NULL)
goto no_client; 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; struct impl *impl;
const char *name, *str; const char *name, *str;
bool promiscuous; 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); pw_log_debug("protocol-jack %p: new", impl);
impl->core = core; impl->core = core;
impl->module = module;
impl->properties = properties; impl->properties = properties;
spa_list_init(&impl->socket_list); 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) bool pipewire__module_init(struct pw_module *module, const char *args)
{ {
module_new(module->core, NULL); module_init(module, NULL);
return true; return true;
} }

View file

@ -32,6 +32,7 @@
struct impl { struct impl {
struct pw_core *core; struct pw_core *core;
struct pw_module *module;
struct pw_properties *properties; struct pw_properties *properties;
void *hnd; void *hnd;
@ -109,7 +110,8 @@ static struct pw_node *make_node(struct impl *impl)
} }
spa_clock = iface; 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; return node;
@ -120,8 +122,9 @@ static struct pw_node *make_node(struct impl *impl)
return NULL; 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 impl *impl;
struct pw_node *n; 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); pw_log_debug("module %p: new", impl);
impl->core = core; impl->core = core;
impl->module = module;
impl->properties = properties; impl->properties = properties;
impl->factory = find_factory(impl); 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++; n->idle_used_input_links++;
node->idle_used_output_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; return impl;
} }
@ -178,6 +182,5 @@ static void module_destroy(struct impl *impl)
bool pipewire__module_init(struct pw_module *module, const char *args) bool pipewire__module_init(struct pw_module *module, const char *args)
{ {
module_new(module->core, NULL); return module_init(module, NULL);
return true;
} }

View file

@ -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); typedef bool(*demarshal_func_t) (void *object, void *data, size_t size);
struct protocol_data {
struct pw_module *module;
};
struct connection { struct connection {
struct pw_protocol_connection this; struct pw_protocol_connection this;
@ -82,10 +86,6 @@ struct listener {
struct spa_loop_control_hooks hooks; struct spa_loop_control_hooks hooks;
}; };
struct protocol_data {
void *unused;
};
struct client_data { struct client_data {
int fd; int fd;
struct spa_source *source; struct spa_source *source;
@ -198,6 +198,7 @@ static struct pw_client *client_new(struct listener *l, int fd)
struct client_data *this; struct client_data *this;
struct pw_client *client; struct pw_client *client;
struct pw_protocol *protocol = l->this.protocol; struct pw_protocol *protocol = l->this.protocol;
struct protocol_data *pd = protocol->user_data;
socklen_t len; socklen_t len;
struct ucred ucred, *ucredp; struct ucred ucred, *ucredp;
@ -209,7 +210,7 @@ static struct pw_client *client_new(struct listener *l, int fd)
ucredp = &ucred; 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) if (client == NULL)
goto no_client; goto no_client;
@ -698,14 +699,16 @@ const static struct pw_protocol_native_ext protocol_ext_impl = {
impl_ext_end_resource, 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; struct pw_protocol *this;
const char *val; const char *val;
struct protocol_data *d;
this = pw_protocol_new(core, PW_TYPE_PROTOCOL__Native, sizeof(struct protocol_data)); this = pw_protocol_new(core, PW_TYPE_PROTOCOL__Native, sizeof(struct protocol_data));
if (this == NULL) if (this == NULL)
return NULL; return false;
this->implementation = &protocol_impl; this->implementation = &protocol_impl;
this->extension = &protocol_ext_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); 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 ((val = pw_properties_get(core->properties, "pipewire.daemon"))) {
if (atoi(val) == 1) if (atoi(val) == 1)
impl_add_listener(this, core, properties); impl_add_listener(this, core, properties);
} }
return this; return true;
} }
#if 0 #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) bool pipewire__module_init(struct pw_module *module, const char *args)
{ {
pw_protocol_native_new(module->core, NULL); return module_init(module, NULL);
return true;
} }

View file

@ -529,7 +529,8 @@ static bool core_demarshal_update_types_server(void *object, void *data, size_t
return true; 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 pw_resource *resource = object;
struct spa_pod_builder *b; 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_builder_struct(b, &f,
SPA_POD_TYPE_INT, id, SPA_POD_TYPE_INT, id,
SPA_POD_TYPE_INT, parent_id,
SPA_POD_TYPE_ID, type, SPA_POD_TYPE_ID, type,
SPA_POD_TYPE_INT, version); 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_builder_add(b,
SPA_POD_TYPE_STRUCT, &f, 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++) { for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b, 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 pw_proxy *proxy = object;
struct spa_pod_iter it; 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) || if (!spa_pod_iter_struct(&it, data, size) ||
!pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &proxy->remote->types) || !pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &proxy->remote->types) ||
!spa_pod_iter_get(&it, !spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &id, SPA_POD_TYPE_INT, &id,
SPA_POD_TYPE_INT, &parent_id,
SPA_POD_TYPE_ID, &type, SPA_POD_TYPE_ID, &type,
SPA_POD_TYPE_INT, &version, 0)) SPA_POD_TYPE_INT, &version, 0))
return false; 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; return true;
} }

View file

@ -49,7 +49,7 @@ bool pipewire__module_init(struct pw_module *module, const char *args)
if ((dir = getenv("SPA_PLUGIN_DIR")) == NULL) if ((dir = getenv("SPA_PLUGIN_DIR")) == NULL)
dir = PLUGINDIR; 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); pw_free_strv(argv);

View file

@ -53,6 +53,7 @@ static struct pw_node *create_node(struct pw_node_factory *factory,
goto no_properties; goto no_properties;
node = pw_spa_node_load(factory->core, node = pw_spa_node_load(factory->core,
NULL,
NULL, NULL,
lib, lib,
factory_name, factory_name,
@ -81,11 +82,15 @@ static struct pw_node *create_node(struct pw_node_factory *factory,
return NULL; 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 impl *impl;
impl = calloc(1, sizeof(struct impl)); impl = calloc(1, sizeof(struct impl));
if (impl == NULL)
return false;
pw_log_debug("module %p: new", impl); pw_log_debug("module %p: new", impl);
impl->properties = properties; 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); spa_list_insert(core->node_factory_list.prev, &impl->this.link);
pw_core_add_global(core, NULL, core->type.node_factory, 0, impl->this.global = pw_core_add_global(core, NULL, module->global, core->type.node_factory, 0,
NULL, impl, &impl->this.global); NULL, impl);
return impl; return true;
} }
#if 0 #if 0
@ -114,6 +119,5 @@ static void module_destroy(struct impl *impl)
bool pipewire__module_init(struct pw_module *module, const char *args) bool pipewire__module_init(struct pw_module *module, const char *args)
{ {
module_new(module->core, NULL); return module_init(module, NULL);
return true;
} }

View file

@ -60,7 +60,7 @@ bool pipewire__module_init(struct pw_module *module, const char *args)
pw_free_strv(prop); 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); pw_free_strv(argv);

View file

@ -47,6 +47,7 @@ struct impl {
struct pw_spa_monitor this; struct pw_spa_monitor this;
struct pw_core *core; struct pw_core *core;
struct pw_global *parent;
void *hnd; 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 = calloc(1, sizeof(struct monitor_item));
mitem->id = strdup(id); 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); 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_spa_monitor *pw_spa_monitor_load(struct pw_core *core,
struct pw_global *parent,
const char *dir, const char *dir,
const char *lib, const char *lib,
const char *factory_name, const char *system_name) 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 = calloc(1, sizeof(struct impl));
impl->core = core; impl->core = core;
impl->parent = parent;
impl->hnd = hnd; impl->hnd = hnd;
this = &impl->this; this = &impl->this;

View file

@ -41,6 +41,7 @@ struct pw_spa_monitor {
struct pw_spa_monitor * struct pw_spa_monitor *
pw_spa_monitor_load(struct pw_core *core, pw_spa_monitor_load(struct pw_core *core,
struct pw_global *parent,
const char *dir, const char *dir,
const char *lib, const char *lib,
const char *factory_name, const char *system_name); const char *factory_name, const char *system_name);

View file

@ -387,6 +387,7 @@ static const struct spa_node_callbacks node_callbacks = {
struct pw_node * struct pw_node *
pw_spa_node_new(struct pw_core *core, pw_spa_node_new(struct pw_core *core,
struct pw_resource *owner, struct pw_resource *owner,
struct pw_global *parent,
const char *name, const char *name,
bool async, bool async,
struct spa_node *node, struct spa_node *node,
@ -411,7 +412,7 @@ pw_spa_node_new(struct pw_core *core,
node->info->items[i].value); 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) if (this == NULL)
return 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_node *pw_spa_node_load(struct pw_core *core,
struct pw_resource *owner, struct pw_resource *owner,
struct pw_global *parent,
const char *lib, const char *lib,
const char *factory_name, const char *factory_name,
const char *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->hnd = hnd;
impl->handle = handle; impl->handle = handle;
impl->lib = filename; impl->lib = filename;

View file

@ -30,6 +30,7 @@ extern "C" {
struct pw_node * struct pw_node *
pw_spa_node_new(struct pw_core *core, pw_spa_node_new(struct pw_core *core,
struct pw_resource *owner, /**< optional owner */ struct pw_resource *owner, /**< optional owner */
struct pw_global *parent, /**< optional parent */
const char *name, const char *name,
bool async, bool async,
struct spa_node *node, struct spa_node *node,
@ -39,6 +40,7 @@ pw_spa_node_new(struct pw_core *core,
struct pw_node * struct pw_node *
pw_spa_node_load(struct pw_core *core, pw_spa_node_load(struct pw_core *core,
struct pw_resource *owner, /**< optional owner */ struct pw_resource *owner, /**< optional owner */
struct pw_global *parent, /**< optional parent */
const char *lib, const char *lib,
const char *factory_name, const char *factory_name,
const char *name, const char *name,

View file

@ -78,6 +78,7 @@ client_bind_func(struct pw_global *global,
* \memberof pw_client * \memberof pw_client
*/ */
struct pw_client *pw_client_new(struct pw_core *core, struct pw_client *pw_client_new(struct pw_core *core,
struct pw_global *parent,
struct ucred *ucred, struct ucred *ucred,
struct pw_properties *properties, struct pw_properties *properties,
size_t user_data_size) 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); 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->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; return this;
} }

View file

@ -127,6 +127,7 @@ struct pw_client {
struct pw_client * struct pw_client *
pw_client_new(struct pw_core *core, pw_client_new(struct pw_core *core,
struct pw_global *parent,
struct ucred *ucred, struct ucred *ucred,
struct pw_properties *properties, struct pw_properties *properties,
size_t user_data_size); size_t user_data_size);

View file

@ -69,7 +69,6 @@ static void registry_bind(void *object, uint32_t id,
struct pw_client *client = resource->client; struct pw_client *client = resource->client;
struct pw_core *core = resource->core; struct pw_core *core = resource->core;
struct pw_global *global; struct pw_global *global;
const char *type_name;
if ((global = find_global(core, id)) == 0) if ((global = find_global(core, id)) == 0)
goto no_id; goto no_id;
@ -80,9 +79,8 @@ static void registry_bind(void *object, uint32_t id,
if (type != global->type) if (type != global->type)
goto wrong_interface; 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,
spa_type_map_get_type(core->type.map, type), new_id);
pw_log_debug("global %p: bind global id %d, iface %s to %d", global, id, type_name, new_id);
pw_global_bind(global, client, version, 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)) { if (pw_global_is_visible(global, client)) {
pw_registry_resource_global(registry_resource, pw_registry_resource_global(registry_resource,
global->id, global->id,
global->parent->id,
global->type, global->type,
global->version); 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_added);
pw_signal_init(&this->global_removed); 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.change_mask = 0;
this->info.user_name = pw_get_user_name(); this->info.user_name = pw_get_user_name();
this->info.host_name = pw_get_host_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->info.name = pw_properties_get(properties, "pipewire.core.name");
this->properties = properties; this->properties = properties;
this->global = pw_core_add_global(this, NULL, NULL, this->type.core, PW_VERSION_CORE,
core_bind_func, this);
return this; return this;
no_data_loop: no_data_loop:
@ -422,23 +421,22 @@ void pw_core_destroy(struct pw_core *core)
* *
* \memberof pw_core * \memberof pw_core
*/ */
bool struct pw_global *
pw_core_add_global(struct pw_core *core, pw_core_add_global(struct pw_core *core,
struct pw_resource *owner, struct pw_resource *owner,
struct pw_global *parent,
uint32_t type, uint32_t type,
uint32_t version, uint32_t version,
pw_bind_func_t bind, pw_bind_func_t bind,
void *object, void *object)
struct pw_global **global)
{ {
struct global_impl *impl; struct global_impl *impl;
struct pw_global *this; struct pw_global *this;
struct pw_resource *registry; struct pw_resource *registry;
const char *type_name;
impl = calloc(1, sizeof(struct global_impl)); impl = calloc(1, sizeof(struct global_impl));
if (impl == NULL) if (impl == NULL)
return false; return NULL;
this = &impl->this; this = &impl->this;
@ -448,24 +446,31 @@ pw_core_add_global(struct pw_core *core,
this->version = version; this->version = version;
this->bind = bind; this->bind = bind;
this->object = object; this->object = object;
*global = this;
pw_signal_init(&this->destroy_signal); pw_signal_init(&this->destroy_signal);
this->id = pw_map_insert_new(&core->objects, this); 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); spa_list_insert(core->global_list.prev, &this->link);
pw_signal_emit(&core->global_added, core, this); 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,
spa_type_map_get_type(core->type.map, this->type), owner);
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) spa_list_for_each(registry, &core->registry_resource_list, link)
if (pw_global_is_visible(this, registry->client)) 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 /** Bind to a global

View file

@ -127,6 +127,7 @@ struct pw_global {
struct spa_list link; /**< link in core list of globals */ struct spa_list link; /**< link in core list of globals */
uint32_t id; /**< server id of the object */ uint32_t id; /**< server id of the object */
struct pw_global *parent; /**< parent global */
uint32_t type; /**< type of interface */ uint32_t type; /**< type of interface */
uint32_t version; /**< version of interface */ uint32_t version; /**< version of interface */
@ -204,14 +205,14 @@ pw_core_destroy(struct pw_core *core);
void void
pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict); 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, pw_core_add_global(struct pw_core *core,
struct pw_resource *owner, struct pw_resource *owner,
struct pw_global *parent,
uint32_t type, uint32_t type,
uint32_t version, uint32_t version,
pw_bind_func_t bind, pw_bind_func_t bind,
void *object, void *object);
struct pw_global **global);
int int
pw_global_bind(struct pw_global *global, pw_global_bind(struct pw_global *global,

View file

@ -364,10 +364,11 @@ struct pw_registry_events {
* available. * available.
* *
* \param id the global object id * \param id the global object id
* \param parent_id the parent global id
* \param type the type of the interface * \param type the type of the interface
* \param version the version 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 * Notify of a global object removal
* *

View file

@ -987,6 +987,7 @@ do_add_link(struct spa_loop *loop,
} }
struct pw_link *pw_link_new(struct pw_core *core, struct pw_link *pw_link_new(struct pw_core *core,
struct pw_global *parent,
struct pw_port *output, struct pw_port *output,
struct pw_port *input, struct pw_port *input,
struct spa_format *format_filter, 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); 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_node_id = output ? output_node->global->id : -1;
this->info.output_port_id = output ? output->port_id : -1; this->info.output_port_id = output ? output->port_id : -1;
this->info.input_node_id = input ? input_node->global->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, do_add_link,
SPA_ID_INVALID, sizeof(struct pw_port *), &input, false, this); 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; return this;
same_ports: same_ports:

View file

@ -95,6 +95,7 @@ struct pw_link {
* \return a newly allocated link */ * \return a newly allocated link */
struct pw_link * struct pw_link *
pw_link_new(struct pw_core *core, /**< the core object */ 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 *output, /**< an output port */
struct pw_port *input, /**< an input port */ struct pw_port *input, /**< an input port */
struct spa_format *format_filter, /**< an optional format filter */ struct spa_format *format_filter, /**< an optional format filter */

View file

@ -180,17 +180,18 @@ struct pw_module *pw_module_load(struct pw_core *core,
pw_signal_init(&this->destroy_signal); 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.name = name ? strdup(name) : NULL;
this->info.filename = filename; this->info.filename = filename;
this->info.args = args ? strdup(args) : NULL; this->info.args = args ? strdup(args) : NULL;
this->info.props = 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); pw_log_debug("loaded module: %s", this->info.name);
return this; return this;

View file

@ -34,6 +34,8 @@
struct impl { struct impl {
struct pw_node this; struct pw_node this;
struct pw_global *parent;
struct pw_work_queue *work; struct pw_work_queue *work;
struct pw_listener on_async_complete; struct pw_listener on_async_complete;
struct pw_listener on_event; struct pw_listener on_event;
@ -255,20 +257,20 @@ do_node_add(struct spa_loop *loop,
void pw_node_export(struct pw_node *this) void pw_node_export(struct pw_node *this)
{ {
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
struct pw_core *core = this->core;
pw_log_debug("node %p: export", this); pw_log_debug("node %p: export", this);
spa_list_insert(this->core->node_list.prev, &this->link); update_info(this);
pw_core_add_global(this->core, this->owner, this->core->type.node, PW_VERSION_NODE,
node_bind_func, this, &this->global);
pw_loop_invoke(this->data_loop, do_node_add, 1, 0, NULL, false, 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; impl->exported = true;
pw_signal_emit(&this->initialized, this); pw_signal_emit(&this->initialized, this);
pw_node_update_state(this, PW_NODE_STATE_SUSPENDED, NULL); 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_node *pw_node_new(struct pw_core *core,
struct pw_resource *owner, struct pw_resource *owner,
struct pw_global *parent,
const char *name, const char *name,
struct pw_properties *properties, struct pw_properties *properties,
size_t user_data_size) 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); this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void);
impl->work = pw_work_queue_new(this->core->main_loop); impl->work = pw_work_queue_new(this->core->main_loop);
impl->parent = parent;
this->info.name = strdup(name); this->info.name = strdup(name);
this->properties = properties; this->properties = properties;

View file

@ -148,6 +148,7 @@ struct pw_node {
struct pw_node * struct pw_node *
pw_node_new(struct pw_core *core, /**< the core */ pw_node_new(struct pw_core *core, /**< the core */
struct pw_resource *owner, /**< optional owner */ struct pw_resource *owner, /**< optional owner */
struct pw_global *parent, /**< optional parent */
const char *name, /**< node name */ const char *name, /**< node name */
struct pw_properties *properties, /**< extra properties */ struct pw_properties *properties, /**< extra properties */
size_t user_data_size /**< user data size */); size_t user_data_size /**< user data size */);

View file

@ -39,6 +39,7 @@ struct data {
struct proxy_data { struct proxy_data {
uint32_t id; uint32_t id;
uint32_t parent_id;
uint32_t version; uint32_t version;
void *info; 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); info = data->info = pw_module_info_update(data->info, info);
printf("\tid: %d\n", data->id); 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); printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Module, data->version);
if (print_all) { if (print_all) {
printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); 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); info = data->info = pw_node_info_update(data->info, info);
printf("\tid: %d\n", data->id); 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); printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Node, data->version);
if (print_all) { if (print_all) {
int i; 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); info = data->info = pw_client_info_update(data->info, info);
printf("\tid: %d\n", data->id); 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); printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Client, data->version);
if (print_all) { if (print_all) {
print_properties(info->props, MARK_CHANGE(0)); 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); info = data->info = pw_link_info_update(data->info, info);
printf("\tid: %d\n", data->id); 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); printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Link, data->version);
if (print_all) { if (print_all) {
printf("%c\toutput-node-id: %u\n", MARK_CHANGE(0), info->output_node_id); 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 pw_proxy *proxy = object;
struct data *data = 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 { else {
printf("added:\n"); printf("added:\n");
printf("\tid: %u\n", id); 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); printf("\ttype: %s (version %d)\n", spa_type_map_get_type(core->type.map, type), version);
return; return;
} }
@ -291,6 +298,7 @@ static void registry_event_global(void *object, uint32_t id, uint32_t type, uint
pd = proxy->user_data; pd = proxy->user_data;
pd->id = id; pd->id = id;
pd->parent_id = parent_id;
pd->version = version; pd->version = version;
pw_proxy_add_listener(proxy, proxy, events); pw_proxy_add_listener(proxy, proxy, events);