mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
Use more fine grained access control
Make it possible to add more permissions to an object than just visible or not. Pass these permissions to the client. This way we can make a difference between being able to see and read, modify or query an object. More permissions can be added later when needed. Because the permissions is set on the resource by the access control module, the implementations can check if the right permission is set before doing anything.
This commit is contained in:
parent
c59bc457d4
commit
4f08dbcd24
14 changed files with 110 additions and 59 deletions
|
|
@ -328,7 +328,7 @@ static const struct pw_node_events node_events = {
|
|||
};
|
||||
|
||||
|
||||
static void registry_event_global(void *object, uint32_t id, uint32_t parent_id,
|
||||
static void registry_event_global(void *object, uint32_t id, uint32_t parent_id, uint32_t permissions,
|
||||
uint32_t type, uint32_t version)
|
||||
{
|
||||
struct pw_registry_proxy *registry = object;
|
||||
|
|
|
|||
|
|
@ -211,14 +211,14 @@ check_global_owner(struct pw_core *core, struct pw_client *client, struct pw_glo
|
|||
if (global->owner == NULL)
|
||||
return true;
|
||||
|
||||
if (global->owner->client->ucred.uid == client->ucred.uid)
|
||||
if (global->owner->ucred.uid == client->ucred.uid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
do_global_filter(struct pw_global *global, struct pw_client *client, void *data)
|
||||
static uint32_t
|
||||
do_permission(struct pw_global *global, struct pw_client *client, void *data)
|
||||
{
|
||||
if (global->type == client->core->type.link) {
|
||||
struct pw_link *link = global->object;
|
||||
|
|
@ -226,16 +226,16 @@ do_global_filter(struct pw_global *global, struct pw_client *client, void *data)
|
|||
/* we must be able to see both nodes */
|
||||
if (link->output
|
||||
&& !check_global_owner(client->core, client, link->output->node->global))
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
if (link->input
|
||||
&& !check_global_owner(client->core, client, link->input->node->global))
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
else if (!check_global_owner(client->core, client, global))
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
return true;
|
||||
return PW_PERM_RWX;
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
|
|
@ -691,8 +691,8 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope
|
|||
|
||||
pw_signal_add(&core->global_added, &impl->global_added, on_global_added);
|
||||
pw_signal_add(&core->global_removed, &impl->global_removed, on_global_removed);
|
||||
core->global_filter = do_global_filter;
|
||||
core->global_filter_data = impl;
|
||||
core->permission_func = do_permission;
|
||||
core->permission_data = impl;
|
||||
|
||||
return impl;
|
||||
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ static struct pw_client *client_new(struct listener *l, int fd)
|
|||
|
||||
pw_signal_add(&client->busy_changed, &this->busy_changed, on_busy_changed);
|
||||
|
||||
pw_global_bind(protocol->core->global, client, PW_VERSION_CORE, 0);
|
||||
pw_global_bind(protocol->core->global, client, PW_PERM_RWX, PW_VERSION_CORE, 0);
|
||||
|
||||
return client;
|
||||
|
||||
|
|
|
|||
|
|
@ -529,7 +529,7 @@ 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 parent_id,
|
||||
static void registry_marshal_global(void *object, uint32_t id, uint32_t parent_id, uint32_t permissions,
|
||||
uint32_t type, uint32_t version)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
|
|
@ -541,6 +541,7 @@ static void registry_marshal_global(void *object, uint32_t id, uint32_t parent_i
|
|||
spa_pod_builder_struct(b, &f,
|
||||
SPA_POD_TYPE_INT, id,
|
||||
SPA_POD_TYPE_INT, parent_id,
|
||||
SPA_POD_TYPE_INT, permissions,
|
||||
SPA_POD_TYPE_ID, type,
|
||||
SPA_POD_TYPE_INT, version);
|
||||
|
||||
|
|
@ -827,18 +828,19 @@ 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, parent_id, type, version;
|
||||
uint32_t id, parent_id, permissions, 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_INT, &permissions,
|
||||
SPA_POD_TYPE_ID, &type,
|
||||
SPA_POD_TYPE_INT, &version, 0))
|
||||
return false;
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_registry_events, global, id, parent_id, type, version);
|
||||
pw_proxy_notify(proxy, struct pw_registry_events, global, id, parent_id, permissions, type, version);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,13 +39,13 @@ static void client_unbind_func(void *data)
|
|||
|
||||
static int
|
||||
client_bind_func(struct pw_global *global,
|
||||
struct pw_client *client,
|
||||
struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
struct pw_client *this = global->object;
|
||||
struct pw_resource *resource;
|
||||
|
||||
resource = pw_resource_new(client, id, global->type, version, 0, client_unbind_func);
|
||||
resource = pw_resource_new(client, id, permissions, global->type, version, 0, client_unbind_func);
|
||||
if (resource == NULL)
|
||||
goto no_mem;
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ struct pw_client *pw_client_new(struct pw_core *core,
|
|||
|
||||
this->info.props = this->properties ? &this->properties->dict : NULL;
|
||||
|
||||
this->global = pw_core_add_global(core, NULL, parent, core->type.client, PW_VERSION_CLIENT,
|
||||
this->global = pw_core_add_global(core, this, parent, core->type.client, PW_VERSION_CLIENT,
|
||||
client_bind_func, this);
|
||||
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -43,15 +43,19 @@ struct impl {
|
|||
|
||||
/** \endcond */
|
||||
|
||||
static bool pw_global_is_visible(struct pw_global *global,
|
||||
struct pw_client *client)
|
||||
static inline uint32_t pw_global_permissions(struct pw_global *global,
|
||||
struct pw_client *client)
|
||||
{
|
||||
struct pw_core *core = client->core;
|
||||
|
||||
return (core->global_filter == NULL ||
|
||||
core->global_filter(global, client, core->global_filter_data));
|
||||
if (core->permission_func == NULL)
|
||||
return PW_PERM_RWX;
|
||||
|
||||
return core->permission_func(global, client, core->permission_data);
|
||||
}
|
||||
|
||||
#define PW_PERM_IS_R(p) (((p)&PW_PERM_R) == PW_PERM_R)
|
||||
|
||||
static struct pw_global *find_global(struct pw_core *core, uint32_t id)
|
||||
{
|
||||
struct pw_global *global;
|
||||
|
|
@ -69,11 +73,14 @@ 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;
|
||||
uint32_t permissions;
|
||||
|
||||
if ((global = find_global(core, id)) == 0)
|
||||
goto no_id;
|
||||
|
||||
if (!pw_global_is_visible(global, client))
|
||||
permissions = pw_global_permissions(global, client);
|
||||
|
||||
if (!PW_PERM_IS_R(permissions))
|
||||
goto no_id;
|
||||
|
||||
if (type != global->type)
|
||||
|
|
@ -82,7 +89,7 @@ static void registry_bind(void *object, uint32_t 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);
|
||||
pw_global_bind(global, client, permissions, version, new_id);
|
||||
|
||||
return;
|
||||
|
||||
|
|
@ -136,6 +143,7 @@ static void core_get_registry(void *object, uint32_t version, uint32_t new_id)
|
|||
|
||||
registry_resource = pw_resource_new(client,
|
||||
new_id,
|
||||
PW_PERM_RWX,
|
||||
this->type.registry,
|
||||
version,
|
||||
0, destroy_registry_resource);
|
||||
|
|
@ -149,10 +157,12 @@ static void core_get_registry(void *object, uint32_t version, uint32_t new_id)
|
|||
spa_list_insert(this->registry_resource_list.prev, ®istry_resource->link);
|
||||
|
||||
spa_list_for_each(global, &this->global_list, link) {
|
||||
if (pw_global_is_visible(global, client)) {
|
||||
uint32_t permissions = pw_global_permissions(global, client);
|
||||
if (PW_PERM_IS_R(permissions)) {
|
||||
pw_registry_resource_global(registry_resource,
|
||||
global->id,
|
||||
global->parent->id,
|
||||
permissions,
|
||||
global->type,
|
||||
global->version);
|
||||
}
|
||||
|
|
@ -185,7 +195,7 @@ core_create_node(void *object,
|
|||
if (factory == NULL)
|
||||
goto no_factory;
|
||||
|
||||
node_resource = pw_resource_new(client, new_id, type, version, 0, NULL);
|
||||
node_resource = pw_resource_new(client, new_id, PW_PERM_RWX, type, version, 0, NULL);
|
||||
if (node_resource == NULL)
|
||||
goto no_resource;
|
||||
|
||||
|
|
@ -274,13 +284,14 @@ static void core_unbind_func(void *data)
|
|||
static int
|
||||
core_bind_func(struct pw_global *global,
|
||||
struct pw_client *client,
|
||||
uint32_t permissions,
|
||||
uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
struct pw_core *this = global->object;
|
||||
struct pw_resource *resource;
|
||||
|
||||
resource = pw_resource_new(client, id, global->type, version, 0, core_unbind_func);
|
||||
resource = pw_resource_new(client, id, permissions, global->type, version, 0, core_unbind_func);
|
||||
if (resource == NULL)
|
||||
goto no_mem;
|
||||
|
||||
|
|
@ -328,7 +339,7 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro
|
|||
this->main_loop = main_loop;
|
||||
|
||||
pw_type_init(&this->type);
|
||||
pw_map_init(&this->objects, 128, 32);
|
||||
pw_map_init(&this->globals, 128, 32);
|
||||
|
||||
spa_graph_init(&this->rt.graph);
|
||||
spa_graph_scheduler_init(&this->rt.sched, &this->rt.graph);
|
||||
|
|
@ -402,7 +413,7 @@ void pw_core_destroy(struct pw_core *core)
|
|||
|
||||
pw_data_loop_destroy(impl->data_loop);
|
||||
|
||||
pw_map_clear(&core->objects);
|
||||
pw_map_clear(&core->globals);
|
||||
|
||||
pw_log_debug("core %p: free", core);
|
||||
free(impl);
|
||||
|
|
@ -424,7 +435,7 @@ void pw_core_destroy(struct pw_core *core)
|
|||
*/
|
||||
struct pw_global *
|
||||
pw_core_add_global(struct pw_core *core,
|
||||
struct pw_resource *owner,
|
||||
struct pw_client *owner,
|
||||
struct pw_global *parent,
|
||||
uint32_t type,
|
||||
uint32_t version,
|
||||
|
|
@ -450,10 +461,10 @@ pw_core_add_global(struct pw_core *core,
|
|||
|
||||
pw_signal_init(&this->destroy_signal);
|
||||
|
||||
this->id = pw_map_insert_new(&core->objects, this);
|
||||
this->id = pw_map_insert_new(&core->globals, this);
|
||||
|
||||
if (owner && owner->client)
|
||||
parent = owner->client->global;
|
||||
if (owner)
|
||||
parent = owner->global;
|
||||
if (parent == NULL)
|
||||
parent = core->global;
|
||||
if (parent == NULL)
|
||||
|
|
@ -466,11 +477,16 @@ pw_core_add_global(struct pw_core *core,
|
|||
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->parent->id,
|
||||
this->type, this->version);
|
||||
|
||||
spa_list_for_each(registry, &core->registry_resource_list, link) {
|
||||
uint32_t permissions = pw_global_permissions(this, registry->client);
|
||||
if (PW_PERM_IS_R(permissions))
|
||||
pw_registry_resource_global(registry,
|
||||
this->id,
|
||||
this->parent->id,
|
||||
permissions,
|
||||
this->type,
|
||||
this->version);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -488,7 +504,7 @@ pw_core_add_global(struct pw_core *core,
|
|||
* \memberof pw_global
|
||||
*/
|
||||
int
|
||||
pw_global_bind(struct pw_global *global, struct pw_client *client,
|
||||
pw_global_bind(struct pw_global *global, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
int res;
|
||||
|
|
@ -499,7 +515,7 @@ pw_global_bind(struct pw_global *global, struct pw_client *client,
|
|||
if (global->version < version)
|
||||
goto wrong_version;
|
||||
|
||||
res = global->bind(global, client, version, id);
|
||||
res = global->bind(global, client, permissions, version, id);
|
||||
|
||||
return res;
|
||||
|
||||
|
|
@ -532,11 +548,13 @@ void pw_global_destroy(struct pw_global *global)
|
|||
pw_log_debug("global %p: destroy %u", global, global->id);
|
||||
pw_signal_emit(&global->destroy_signal, global);
|
||||
|
||||
spa_list_for_each(registry, &core->registry_resource_list, link)
|
||||
if (pw_global_is_visible(global, registry->client))
|
||||
spa_list_for_each(registry, &core->registry_resource_list, link) {
|
||||
uint32_t permissions = pw_global_permissions(global, registry->client);
|
||||
if (PW_PERM_IS_R(permissions))
|
||||
pw_registry_resource_global_remove(registry, global->id);
|
||||
}
|
||||
|
||||
pw_map_remove(&core->objects, global->id);
|
||||
pw_map_remove(&core->globals, global->id);
|
||||
|
||||
spa_list_remove(&global->link);
|
||||
pw_signal_emit(&core->global_removed, core, global);
|
||||
|
|
|
|||
|
|
@ -92,11 +92,17 @@ struct pw_global;
|
|||
*/
|
||||
typedef int (*pw_bind_func_t) (struct pw_global *global, /**< the global to bind */
|
||||
struct pw_client *client, /**< client that binds */
|
||||
uint32_t permissions, /**< permissions for the bind */
|
||||
uint32_t version, /**< client interface version */
|
||||
uint32_t id); /**< client proxy id */
|
||||
|
||||
typedef bool (*pw_global_filter_func_t) (struct pw_global *global,
|
||||
struct pw_client *client, void *data);
|
||||
#define PW_PERM_R 0400 /**< object can be seen and events can be received */
|
||||
#define PW_PERM_W 0200 /**< methods can be called that modify the object */
|
||||
#define PW_PERM_X 0100 /**< methods can be called on the object. The W flag must be
|
||||
* present in order to call methods that modify the object. */
|
||||
#define PW_PERM_RWX (PW_PERM_R|PW_PERM_W|PW_PERM_X)
|
||||
typedef uint32_t (*pw_permission_func_t) (struct pw_global *global,
|
||||
struct pw_client *client, void *data);
|
||||
|
||||
/** \page page_global Global
|
||||
*
|
||||
|
|
@ -122,7 +128,7 @@ typedef bool (*pw_global_filter_func_t) (struct pw_global *global,
|
|||
*/
|
||||
struct pw_global {
|
||||
struct pw_core *core; /**< the core */
|
||||
struct pw_resource *owner; /**< the owner of this object, NULL when the
|
||||
struct pw_client *owner; /**< the owner of this object, NULL when the
|
||||
* PipeWire server is the owner */
|
||||
|
||||
struct spa_list link; /**< link in core list of globals */
|
||||
|
|
@ -157,12 +163,12 @@ struct pw_core {
|
|||
|
||||
struct pw_properties *properties; /**< properties of the core */
|
||||
|
||||
struct pw_type type; /**< type map and common types */
|
||||
struct pw_type type; /**< type map and common types */
|
||||
|
||||
pw_global_filter_func_t global_filter;
|
||||
void *global_filter_data;
|
||||
pw_permission_func_t permission_func; /**< get permissions of an object */
|
||||
void *permission_data; /**< data passed to permission function */
|
||||
|
||||
struct pw_map objects; /**< map of known objects */
|
||||
struct pw_map globals; /**< map of globals */
|
||||
|
||||
struct spa_list protocol_list; /**< list of protocols */
|
||||
struct spa_list remote_list; /**< list of remote connections */
|
||||
|
|
@ -208,7 +214,7 @@ pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict);
|
|||
|
||||
struct pw_global *
|
||||
pw_core_add_global(struct pw_core *core,
|
||||
struct pw_resource *owner,
|
||||
struct pw_client *owner,
|
||||
struct pw_global *parent,
|
||||
uint32_t type,
|
||||
uint32_t version,
|
||||
|
|
@ -218,6 +224,7 @@ pw_core_add_global(struct pw_core *core,
|
|||
int
|
||||
pw_global_bind(struct pw_global *global,
|
||||
struct pw_client *client,
|
||||
uint32_t permissions,
|
||||
uint32_t version,
|
||||
uint32_t id);
|
||||
|
||||
|
|
|
|||
|
|
@ -365,10 +365,12 @@ struct pw_registry_events {
|
|||
*
|
||||
* \param id the global object id
|
||||
* \param parent_id the parent global id
|
||||
* \param permissions the permissions of the object
|
||||
* \param type the type of the interface
|
||||
* \param version the version of the interface
|
||||
*/
|
||||
void (*global) (void *object, uint32_t id, uint32_t parent_id, uint32_t type, uint32_t version);
|
||||
void (*global) (void *object, uint32_t id, uint32_t parent_id,
|
||||
uint32_t permissions, uint32_t type, uint32_t version);
|
||||
/**
|
||||
* Notify of a global object removal
|
||||
*
|
||||
|
|
|
|||
|
|
@ -940,13 +940,13 @@ static void link_unbind_func(void *data)
|
|||
|
||||
static int
|
||||
link_bind_func(struct pw_global *global,
|
||||
struct pw_client *client,
|
||||
struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
struct pw_link *this = global->object;
|
||||
struct pw_resource *resource;
|
||||
|
||||
resource = pw_resource_new(client, id, global->type, version, 0, link_unbind_func);
|
||||
resource = pw_resource_new(client, id, permissions, global->type, version, 0, link_unbind_func);
|
||||
|
||||
if (resource == NULL)
|
||||
goto no_mem;
|
||||
|
|
|
|||
|
|
@ -89,13 +89,13 @@ static char *find_module(const char *path, const char *name)
|
|||
|
||||
static int
|
||||
module_bind_func(struct pw_global *global,
|
||||
struct pw_client *client,
|
||||
struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
struct pw_module *this = global->object;
|
||||
struct pw_resource *resource;
|
||||
|
||||
resource = pw_resource_new(client, id, global->type, version, 0, NULL);
|
||||
resource = pw_resource_new(client, id, permissions, global->type, version, 0, NULL);
|
||||
if (resource == NULL)
|
||||
goto no_mem;
|
||||
|
||||
|
|
|
|||
|
|
@ -229,13 +229,13 @@ clear_info(struct pw_node *this)
|
|||
|
||||
static int
|
||||
node_bind_func(struct pw_global *global,
|
||||
struct pw_client *client,
|
||||
struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
struct pw_node *this = global->object;
|
||||
struct pw_resource *resource;
|
||||
|
||||
resource = pw_resource_new(client, id, global->type, version, 0, node_unbind_func);
|
||||
resource = pw_resource_new(client, id, permissions, global->type, version, 0, node_unbind_func);
|
||||
if (resource == NULL)
|
||||
goto no_mem;
|
||||
|
||||
|
|
@ -282,7 +282,8 @@ void pw_node_register(struct pw_node *this)
|
|||
pw_loop_invoke(this->data_loop, do_node_add, 1, 0, NULL, false, this);
|
||||
|
||||
spa_list_insert(core->node_list.prev, &this->link);
|
||||
this->global = pw_core_add_global(core, this->owner, impl->parent,
|
||||
this->global = pw_core_add_global(core, this->owner ? this->owner->client : NULL,
|
||||
impl->parent,
|
||||
core->type.node, PW_VERSION_NODE,
|
||||
node_bind_func, this);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ struct impl {
|
|||
|
||||
struct pw_resource *pw_resource_new(struct pw_client *client,
|
||||
uint32_t id,
|
||||
uint32_t permissions,
|
||||
uint32_t type,
|
||||
uint32_t version,
|
||||
size_t user_data_size,
|
||||
|
|
@ -46,6 +47,7 @@ struct pw_resource *pw_resource_new(struct pw_client *client,
|
|||
this = &impl->this;
|
||||
this->core = client->core;
|
||||
this->client = client;
|
||||
this->permissions = permissions;
|
||||
this->type = type;
|
||||
this->version = version;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ struct pw_resource {
|
|||
struct pw_client *client; /**< owner client */
|
||||
|
||||
uint32_t id; /**< per client unique id, index in client objects */
|
||||
uint32_t permissions; /**< resource permissions */
|
||||
uint32_t type; /**< type of the client interface */
|
||||
uint32_t version; /**< version of the client interface */
|
||||
|
||||
|
|
@ -85,6 +86,7 @@ struct pw_resource {
|
|||
struct pw_resource *
|
||||
pw_resource_new(struct pw_client *client, /**< the client owning the resource */
|
||||
uint32_t id, /**< the remote per client id */
|
||||
uint32_t permissions, /**< permissions on this resource */
|
||||
uint32_t type, /**< interface of the resource */
|
||||
uint32_t version, /**< requested interface version */
|
||||
size_t user_data_size, /**< extra user data size */
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct data {
|
|||
struct proxy_data {
|
||||
uint32_t id;
|
||||
uint32_t parent_id;
|
||||
uint32_t permissions;
|
||||
uint32_t version;
|
||||
void *info;
|
||||
};
|
||||
|
|
@ -95,6 +96,9 @@ static void module_event_info(void *object, struct pw_module_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__Module, data->version);
|
||||
if (print_all) {
|
||||
printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
|
||||
|
|
@ -129,6 +133,9 @@ static void node_event_info(void *object, struct pw_node_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__Node, data->version);
|
||||
if (print_all) {
|
||||
int i;
|
||||
|
|
@ -178,6 +185,9 @@ static void client_event_info(void *object, struct pw_client_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__Client, data->version);
|
||||
if (print_all) {
|
||||
print_properties(info->props, MARK_CHANGE(0));
|
||||
|
|
@ -209,6 +219,9 @@ static void link_event_info(void *object, struct pw_link_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__Link, data->version);
|
||||
if (print_all) {
|
||||
printf("%c\toutput-node-id: %u\n", MARK_CHANGE(0), info->output_node_id);
|
||||
|
|
@ -258,7 +271,7 @@ destroy_proxy (void *data)
|
|||
|
||||
|
||||
static void registry_event_global(void *object, uint32_t id, uint32_t parent_id,
|
||||
uint32_t type, uint32_t version)
|
||||
uint32_t permissions, uint32_t type, uint32_t version)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct data *data = proxy->object;
|
||||
|
|
@ -287,6 +300,9 @@ static void registry_event_global(void *object, uint32_t id, uint32_t parent_id,
|
|||
printf("added:\n");
|
||||
printf("\tid: %u\n", id);
|
||||
printf("\tparent_id: %d\n", parent_id);
|
||||
printf("\tpermissions: %c%c%c\n", permissions & PW_PERM_R ? 'r' : '-',
|
||||
permissions & PW_PERM_W ? 'w' : '-',
|
||||
permissions & PW_PERM_X ? 'x' : '-');
|
||||
printf("\ttype: %s (version %d)\n", spa_type_map_get_type(core->type.map, type), version);
|
||||
return;
|
||||
}
|
||||
|
|
@ -299,6 +315,7 @@ static void registry_event_global(void *object, uint32_t id, uint32_t parent_id,
|
|||
pd = proxy->user_data;
|
||||
pd->id = id;
|
||||
pd->parent_id = parent_id;
|
||||
pd->permissions = permissions;
|
||||
pd->version = version;
|
||||
pw_proxy_add_listener(proxy, proxy, events);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue