mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
factory: add introspection
This commit is contained in:
parent
7f20e04803
commit
67d4dd8656
10 changed files with 220 additions and 22 deletions
|
|
@ -92,7 +92,7 @@ core_marshal_create_object(void *object,
|
|||
struct spa_pod_frame f;
|
||||
uint32_t i, n_items;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_NODE);
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_OBJECT);
|
||||
|
||||
n_items = props ? props->n_items : 0;
|
||||
|
||||
|
|
@ -630,6 +630,66 @@ static bool module_demarshal_info(void *object, void *data, size_t size)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void factory_marshal_info(void *object, struct pw_factory_info *info)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
struct spa_pod_frame f;
|
||||
uint32_t i, n_items;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_FACTORY_PROXY_EVENT_INFO);
|
||||
|
||||
n_items = info->props ? info->props->n_items : 0;
|
||||
|
||||
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_ID, info->type,
|
||||
SPA_POD_TYPE_INT, info->version,
|
||||
SPA_POD_TYPE_INT, n_items, 0);
|
||||
|
||||
for (i = 0; i < n_items; i++) {
|
||||
spa_pod_builder_add(b,
|
||||
SPA_POD_TYPE_STRING, info->props->items[i].key,
|
||||
SPA_POD_TYPE_STRING, info->props->items[i].value, 0);
|
||||
}
|
||||
spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static bool factory_demarshal_info(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_iter it;
|
||||
struct spa_dict props;
|
||||
struct pw_factory_info info;
|
||||
int i;
|
||||
|
||||
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_ID, &info.type,
|
||||
SPA_POD_TYPE_INT, &info.version,
|
||||
SPA_POD_TYPE_INT, &props.n_items, 0))
|
||||
return false;
|
||||
|
||||
info.props = &props;
|
||||
props.items = alloca(props.n_items * sizeof(struct spa_dict_item));
|
||||
for (i = 0; i < props.n_items; i++) {
|
||||
if (!spa_pod_iter_get(&it,
|
||||
SPA_POD_TYPE_STRING, &props.items[i].key,
|
||||
SPA_POD_TYPE_STRING, &props.items[i].value, 0))
|
||||
return false;
|
||||
}
|
||||
pw_proxy_notify(proxy, struct pw_factory_proxy_events, info, &info);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void node_marshal_info(void *object, struct pw_node_info *info)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
|
|
@ -992,6 +1052,24 @@ const struct pw_protocol_marshal pw_protocol_native_module_marshal = {
|
|||
pw_protocol_native_module_event_demarshal,
|
||||
};
|
||||
|
||||
static const struct pw_factory_proxy_events pw_protocol_native_factory_event_marshal = {
|
||||
PW_VERSION_FACTORY_PROXY_EVENTS,
|
||||
&factory_marshal_info,
|
||||
};
|
||||
|
||||
static const struct pw_protocol_native_demarshal pw_protocol_native_factory_event_demarshal[] = {
|
||||
{ &factory_demarshal_info, PW_PROTOCOL_NATIVE_REMAP, },
|
||||
};
|
||||
|
||||
const struct pw_protocol_marshal pw_protocol_native_factory_marshal = {
|
||||
PW_TYPE_INTERFACE__Factory,
|
||||
PW_VERSION_FACTORY,
|
||||
0, NULL, NULL,
|
||||
PW_FACTORY_PROXY_EVENT_NUM,
|
||||
&pw_protocol_native_factory_event_marshal,
|
||||
pw_protocol_native_factory_event_demarshal,
|
||||
};
|
||||
|
||||
static const struct pw_node_proxy_events pw_protocol_native_node_event_marshal = {
|
||||
PW_VERSION_NODE_PROXY_EVENTS,
|
||||
&node_marshal_info,
|
||||
|
|
@ -1052,6 +1130,7 @@ void pw_protocol_native_init(struct pw_protocol *protocol)
|
|||
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_factory_marshal);
|
||||
pw_protocol_add_marshal(protocol, &pw_protocol_native_client_marshal);
|
||||
pw_protocol_add_marshal(protocol, &pw_protocol_native_link_marshal);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ static void *create_object(void *_data,
|
|||
|
||||
node = pw_spa_node_load(data->core,
|
||||
NULL,
|
||||
NULL,
|
||||
pw_factory_get_global(data->this),
|
||||
lib,
|
||||
factory_name,
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -181,10 +181,10 @@ core_create_object(void *object,
|
|||
if (factory == NULL)
|
||||
goto no_factory;
|
||||
|
||||
if (factory->type != type)
|
||||
if (factory->info.type != type)
|
||||
goto wrong_type;
|
||||
|
||||
if (factory->version < version)
|
||||
if (factory->info.version < version)
|
||||
goto wrong_version;
|
||||
|
||||
if (props) {
|
||||
|
|
@ -795,7 +795,7 @@ struct pw_factory *pw_core_find_factory(struct pw_core *core, const char *name)
|
|||
struct pw_factory *factory;
|
||||
|
||||
spa_list_for_each(factory, &core->factory_list, link) {
|
||||
if (strcmp(factory->name, name) == 0)
|
||||
if (strcmp(factory->info.name, name) == 0)
|
||||
return factory;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -36,12 +36,14 @@ struct pw_factory *pw_factory_new(struct pw_core *core,
|
|||
|
||||
this = calloc(1, sizeof(*this) + user_data_size);
|
||||
this->core = core;
|
||||
this->name = strdup(name);
|
||||
this->type = type;
|
||||
this->version = version;
|
||||
this->properties = properties;
|
||||
spa_list_init(&this->resource_list);
|
||||
|
||||
this->info.name = strdup(name);
|
||||
this->info.type = type;
|
||||
this->info.version = version;
|
||||
this->info.props = properties ? &properties->dict : NULL;
|
||||
|
||||
if (user_data_size > 0)
|
||||
this->user_data = SPA_MEMBER(this, sizeof(*this), void);
|
||||
|
||||
|
|
@ -58,8 +60,10 @@ void pw_factory_destroy(struct pw_factory *factory)
|
|||
spa_list_remove(&factory->link);
|
||||
pw_global_destroy(factory->global);
|
||||
}
|
||||
if (factory->name)
|
||||
free((char *)factory->name);
|
||||
if (factory->info.name)
|
||||
free((char *)factory->info.name);
|
||||
if (factory->properties)
|
||||
pw_properties_free(factory->properties);
|
||||
|
||||
free(factory);
|
||||
}
|
||||
|
|
@ -123,6 +127,11 @@ void *pw_factory_get_user_data(struct pw_factory *factory)
|
|||
return factory->user_data;
|
||||
}
|
||||
|
||||
struct pw_global *pw_factory_get_global(struct pw_factory *factory)
|
||||
{
|
||||
return factory->global;
|
||||
}
|
||||
|
||||
void pw_factory_set_implementation(struct pw_factory *factory,
|
||||
const struct pw_factory_implementation *implementation,
|
||||
void *data)
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ void pw_factory_destroy(struct pw_factory *factory);
|
|||
|
||||
void *pw_factory_get_user_data(struct pw_factory *factory);
|
||||
|
||||
/** Get the global of this factory */
|
||||
struct pw_global *pw_factory_get_global(struct pw_factory *factory);
|
||||
|
||||
void pw_factory_set_implementation(struct pw_factory *factory,
|
||||
const struct pw_factory_implementation *implementation,
|
||||
void *data);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ struct pw_link_proxy;
|
|||
#define PW_CORE_PROXY_METHOD_SYNC 1
|
||||
#define PW_CORE_PROXY_METHOD_GET_REGISTRY 2
|
||||
#define PW_CORE_PROXY_METHOD_CLIENT_UPDATE 3
|
||||
#define PW_CORE_PROXY_METHOD_CREATE_NODE 4
|
||||
#define PW_CORE_PROXY_METHOD_CREATE_OBJECT 4
|
||||
#define PW_CORE_PROXY_METHOD_CREATE_LINK 5
|
||||
#define PW_CORE_PROXY_METHOD_NUM 6
|
||||
|
||||
|
|
|
|||
|
|
@ -273,6 +273,42 @@ void pw_node_info_free(struct pw_node_info *info)
|
|||
free(info);
|
||||
}
|
||||
|
||||
struct pw_factory_info *pw_factory_info_update(struct pw_factory_info *info,
|
||||
const struct pw_factory_info *update)
|
||||
{
|
||||
if (update == NULL)
|
||||
return info;
|
||||
|
||||
if (info == NULL) {
|
||||
info = calloc(1, sizeof(struct pw_factory_info));
|
||||
if (info == NULL)
|
||||
return NULL;
|
||||
}
|
||||
info->id = update->id;
|
||||
if (info->name)
|
||||
free((void *) info->name);
|
||||
info->name = update->name ? strdup(update->name) : NULL;
|
||||
info->type = update->type;
|
||||
info->version = update->version;
|
||||
info->change_mask = update->change_mask;
|
||||
|
||||
if (update->change_mask & PW_FACTORY_CHANGE_MASK_PROPS) {
|
||||
if (info->props)
|
||||
pw_spa_dict_destroy(info->props);
|
||||
info->props = pw_spa_dict_copy(update->props);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
void pw_factory_info_free(struct pw_factory_info *info)
|
||||
{
|
||||
if (info->name)
|
||||
free((void *) info->name);
|
||||
if (info->props)
|
||||
pw_spa_dict_destroy(info->props);
|
||||
free(info);
|
||||
}
|
||||
|
||||
struct pw_module_info *pw_module_info_update(struct pw_module_info *info,
|
||||
const struct pw_module_info *update)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -374,9 +374,6 @@ struct pw_factory {
|
|||
struct pw_global *global; /**< global for this factory */
|
||||
|
||||
struct pw_factory_info info; /**< introspectable factory info */
|
||||
const char *name; /**< the factory name */
|
||||
uint32_t type; /**< the type produced by the factory*/
|
||||
uint32_t version; /**< the version of the produced object */
|
||||
struct pw_properties *properties; /**< properties of the factory */
|
||||
|
||||
const struct pw_factory_implementation *implementation;
|
||||
|
|
|
|||
|
|
@ -543,6 +543,17 @@ static void info_node(struct proxy_data *pd)
|
|||
print_properties(info->props, MARK_CHANGE(6));
|
||||
}
|
||||
|
||||
static void info_factory(struct proxy_data *pd)
|
||||
{
|
||||
struct pw_factory_info *info = pd->info;
|
||||
struct pw_type *t = pd->rd->data->t;
|
||||
|
||||
info_global(pd);
|
||||
fprintf(stdout, "\tname: \"%s\"\n", info->name);
|
||||
fprintf(stdout, "\tobject-type: %s/%d\n", spa_type_map_get_type(t->map, info->type), info->version);
|
||||
print_properties(info->props, MARK_CHANGE(0));
|
||||
}
|
||||
|
||||
static void info_client(struct proxy_data *pd)
|
||||
{
|
||||
struct pw_client_info *info = pd->info;
|
||||
|
|
@ -624,6 +635,24 @@ static const struct pw_node_proxy_events node_events = {
|
|||
.info = node_event_info
|
||||
};
|
||||
|
||||
static void factory_event_info(void *object, struct pw_factory_info *info)
|
||||
{
|
||||
struct proxy_data *pd = object;
|
||||
struct remote_data *rd = pd->rd;
|
||||
pd->info = pw_factory_info_update(pd->info, info);
|
||||
if (pd->global == NULL)
|
||||
pd->global = pw_map_lookup(&rd->globals, info->id);
|
||||
if (pd->global && pd->global->info_pending) {
|
||||
info_factory(pd);
|
||||
pd->global->info_pending = false;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct pw_factory_proxy_events factory_events = {
|
||||
PW_VERSION_FACTORY_PROXY_EVENTS,
|
||||
.info = factory_event_info
|
||||
};
|
||||
|
||||
static void client_event_info(void *object, struct pw_client_info *info)
|
||||
{
|
||||
struct proxy_data *pd = object;
|
||||
|
|
@ -716,6 +745,12 @@ static bool bind_global(struct remote_data *rd, struct global *global, char **er
|
|||
destroy = (pw_destroy_t) pw_node_info_free;
|
||||
info_func = info_node;
|
||||
}
|
||||
else if (global->type == t->factory) {
|
||||
events = &factory_events;
|
||||
client_version = PW_VERSION_FACTORY;
|
||||
destroy = (pw_destroy_t) pw_factory_info_free;
|
||||
info_func = info_factory;
|
||||
}
|
||||
else if (global->type == t->client) {
|
||||
events = &client_events;
|
||||
client_version = PW_VERSION_CLIENT;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct data {
|
|||
};
|
||||
|
||||
struct proxy_data {
|
||||
struct data *data;
|
||||
struct pw_proxy *proxy;
|
||||
uint32_t id;
|
||||
uint32_t parent_id;
|
||||
|
|
@ -86,8 +87,7 @@ static void on_info_changed(void *data, const struct pw_core_info *info)
|
|||
|
||||
static void module_event_info(void *object, struct pw_module_info *info)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct proxy_data *data = pw_proxy_get_user_data(proxy);
|
||||
struct proxy_data *data = object;
|
||||
bool print_all, print_mark;
|
||||
|
||||
print_all = true;
|
||||
|
|
@ -123,8 +123,7 @@ static const struct pw_module_proxy_events module_events = {
|
|||
|
||||
static void node_event_info(void *object, struct pw_node_info *info)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct proxy_data *data = pw_proxy_get_user_data(proxy);
|
||||
struct proxy_data *data = object;
|
||||
bool print_all, print_mark;
|
||||
|
||||
print_all = true;
|
||||
|
|
@ -173,10 +172,45 @@ static const struct pw_node_proxy_events node_events = {
|
|||
.info = node_event_info
|
||||
};
|
||||
|
||||
static void factory_event_info(void *object, struct pw_factory_info *info)
|
||||
{
|
||||
struct proxy_data *data = object;
|
||||
struct pw_type *t = pw_core_get_type(data->data->core);
|
||||
bool print_all, print_mark;
|
||||
|
||||
print_all = true;
|
||||
if (data->info == NULL) {
|
||||
printf("added:\n");
|
||||
print_mark = false;
|
||||
}
|
||||
else {
|
||||
printf("changed:\n");
|
||||
print_mark = true;
|
||||
}
|
||||
|
||||
info = data->info = pw_factory_info_update(data->info, info);
|
||||
|
||||
printf("\tid: %d\n", data->id);
|
||||
printf("\tparent_id: %d\n", data->parent_id);
|
||||
printf("\tpermissions: %c%c%c\n", data->permissions & PW_PERM_R ? 'r' : '-',
|
||||
data->permissions & PW_PERM_W ? 'w' : '-',
|
||||
data->permissions & PW_PERM_X ? 'x' : '-');
|
||||
printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Factory, data->version);
|
||||
printf("\tname: \"%s\"\n", info->name);
|
||||
printf("\tobject-type: %s/%d\n", spa_type_map_get_type(t->map, info->type), info->version);
|
||||
if (print_all) {
|
||||
print_properties(info->props, MARK_CHANGE(0));
|
||||
}
|
||||
}
|
||||
|
||||
static const struct pw_factory_proxy_events factory_events = {
|
||||
PW_VERSION_FACTORY_PROXY_EVENTS,
|
||||
.info = factory_event_info
|
||||
};
|
||||
|
||||
static void client_event_info(void *object, struct pw_client_info *info)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct proxy_data *data = pw_proxy_get_user_data(proxy);
|
||||
struct proxy_data *data = object;
|
||||
bool print_all, print_mark;
|
||||
|
||||
print_all = true;
|
||||
|
|
@ -209,8 +243,7 @@ static const struct pw_client_proxy_events client_events = {
|
|||
|
||||
static void link_event_info(void *object, struct pw_link_info *info)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct proxy_data *data = pw_proxy_get_user_data(proxy);
|
||||
struct proxy_data *data = object;
|
||||
bool print_all, print_mark;
|
||||
|
||||
print_all = true;
|
||||
|
|
@ -290,6 +323,11 @@ static void registry_event_global(void *data, uint32_t id, uint32_t parent_id,
|
|||
client_version = PW_VERSION_MODULE;
|
||||
destroy = (pw_destroy_t) pw_module_info_free;
|
||||
}
|
||||
else if (type == t->factory) {
|
||||
events = &factory_events;
|
||||
client_version = PW_VERSION_FACTORY;
|
||||
destroy = (pw_destroy_t) pw_factory_info_free;
|
||||
}
|
||||
else if (type == t->client) {
|
||||
events = &client_events;
|
||||
client_version = PW_VERSION_CLIENT;
|
||||
|
|
@ -318,6 +356,7 @@ static void registry_event_global(void *data, uint32_t id, uint32_t parent_id,
|
|||
goto no_mem;
|
||||
|
||||
pd = pw_proxy_get_user_data(proxy);
|
||||
pd->data = d;
|
||||
pd->proxy = proxy;
|
||||
pd->id = id;
|
||||
pd->parent_id = parent_id;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue