diff --git a/src/pipewire/core.c b/src/pipewire/core.c index cf47e81ff..0f4663a21 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -57,6 +58,11 @@ struct resource_data { struct spa_hook object_listener; }; +struct factory_entry { + regex_t regex; + char *lib; +}; + /** \endcond */ static void * registry_bind(void *object, uint32_t id, uint32_t type, uint32_t version, size_t user_data_size) @@ -466,6 +472,7 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, this->data_loop = pw_data_loop_get_loop(this->data_loop_impl); this->main_loop = main_loop; + pw_array_init(&this->factory_lib, 32); pw_map_init(&this->globals, 128, 32); this->support[0] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataLoop, this->data_loop->loop); @@ -562,6 +569,7 @@ void pw_core_destroy(struct pw_core *core) struct pw_remote *remote; struct pw_resource *resource; struct pw_node *node; + struct factory_entry *entry; pw_log_debug("core %p: destroy", core); pw_core_emit_destroy(core); @@ -596,6 +604,12 @@ void pw_core_destroy(struct pw_core *core) if (impl->dbus_handle) pw_unload_spa_handle(impl->dbus_handle); + pw_array_for_each(entry, &core->factory_lib) { + regfree(&entry->regex); + free(entry->lib); + } + pw_array_clear(&core->factory_lib); + pw_map_clear(&core->globals); free(core); @@ -1050,3 +1064,42 @@ int pw_core_recalc_graph(struct pw_core *core) } return 0; } + +SPA_EXPORT +int pw_core_add_spa_lib(struct pw_core *core, + const char *factory_regexp, const char *lib) +{ + struct factory_entry *entry; + int err; + + entry = pw_array_add(&core->factory_lib, sizeof(*entry)); + if (entry == NULL) + return -ENOMEM; + + if ((err = regcomp(&entry->regex, factory_regexp, REG_EXTENDED | REG_NOSUB)) != 0) { + char errbuf[1024]; + regerror(err, &entry->regex, errbuf, sizeof(errbuf)); + pw_log_error("can compile regex: %s", errbuf); + + pw_array_remove(&core->factory_lib, entry); + return -EINVAL; + } + + entry->lib = strdup(lib); + pw_log_debug("core %p: map factory regex '%s' to '%s", core, + factory_regexp, lib); + + return 0; +} + +SPA_EXPORT +const char *pw_core_find_spa_lib(struct pw_core *core, const char *factory_name) +{ + struct factory_entry *entry; + + pw_array_for_each(entry, &core->factory_lib) { + if (regexec(&entry->regex, factory_name, 0, NULL, 0) == 0) + return entry->lib; + } + return NULL; +} diff --git a/src/pipewire/core.h b/src/pipewire/core.h index f811a7614..f2b44f0b1 100644 --- a/src/pipewire/core.h +++ b/src/pipewire/core.h @@ -147,6 +147,12 @@ struct pw_factory * pw_core_find_factory(struct pw_core *core /**< the core */, const char *name /**< the factory name */); +/** add a spa library for the given factory_name regex */ +int pw_core_add_spa_lib(struct pw_core *core, const char *factory_regex, const char *lib); + +/** find the library name for a spa factory */ +const char * pw_core_find_spa_lib(struct pw_core *core, const char *factory_name); + #ifdef __cplusplus } #endif diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 02265edcf..f07f74c3a 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -235,6 +235,7 @@ struct pw_core { struct spa_support support[16]; /**< support for spa plugins */ uint32_t n_support; /**< number of support items */ + struct pw_array factory_lib; /**< mapping of factory_name regexp to library */ struct pw_client *current_client; /**< client currently executing code in mainloop */