mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
Add missing file
This commit is contained in:
parent
db15225b51
commit
ac8458dd52
1 changed files with 222 additions and 0 deletions
222
src/pipewire/global.c
Normal file
222
src/pipewire/global.c
Normal file
|
|
@ -0,0 +1,222 @@
|
||||||
|
/* PipeWire
|
||||||
|
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <spa/lib/debug.h>
|
||||||
|
|
||||||
|
#include <pipewire/pipewire.h>
|
||||||
|
#include <pipewire/private.h>
|
||||||
|
#include <pipewire/global.h>
|
||||||
|
|
||||||
|
/** \cond */
|
||||||
|
struct global_impl {
|
||||||
|
struct pw_global this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \endcond */
|
||||||
|
|
||||||
|
uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *client)
|
||||||
|
{
|
||||||
|
struct pw_core *core = client->core;
|
||||||
|
|
||||||
|
if (core->permission_func == NULL)
|
||||||
|
return PW_PERM_RWX;
|
||||||
|
|
||||||
|
return core->permission_func(global, client, core->permission_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create and add a new global to the core
|
||||||
|
*
|
||||||
|
* \param core a core
|
||||||
|
* \param owner an optional owner of the global
|
||||||
|
* \param type the type of the global
|
||||||
|
* \param n_ifaces number of interfaces
|
||||||
|
* \param ifaces interface information
|
||||||
|
* \param object the associated object
|
||||||
|
* \param bind a function to bind to this global
|
||||||
|
* \param[out] global a result global
|
||||||
|
* \return true on success
|
||||||
|
*
|
||||||
|
* \memberof pw_core
|
||||||
|
*/
|
||||||
|
struct pw_global *
|
||||||
|
pw_core_add_global(struct pw_core *core,
|
||||||
|
struct pw_client *owner,
|
||||||
|
struct pw_global *parent,
|
||||||
|
uint32_t type,
|
||||||
|
uint32_t version,
|
||||||
|
pw_bind_func_t bind,
|
||||||
|
void *object)
|
||||||
|
{
|
||||||
|
struct global_impl *impl;
|
||||||
|
struct pw_global *this;
|
||||||
|
struct pw_resource *registry;
|
||||||
|
|
||||||
|
impl = calloc(1, sizeof(struct global_impl));
|
||||||
|
if (impl == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
this = &impl->this;
|
||||||
|
|
||||||
|
this->core = core;
|
||||||
|
this->owner = owner;
|
||||||
|
this->type = type;
|
||||||
|
this->version = version;
|
||||||
|
this->bind = bind;
|
||||||
|
this->object = object;
|
||||||
|
|
||||||
|
this->id = pw_map_insert_new(&core->globals, this);
|
||||||
|
|
||||||
|
if (owner)
|
||||||
|
parent = owner->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_hook_list_call(&core->listener_list, struct pw_core_events, global_added, this);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
uint32_t permissions = pw_global_get_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pw_core *pw_global_get_core(struct pw_global *global)
|
||||||
|
{
|
||||||
|
return global->core;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct pw_client *pw_global_get_owner(struct pw_global *global)
|
||||||
|
{
|
||||||
|
return global->owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pw_global *pw_global_get_parent(struct pw_global *global)
|
||||||
|
{
|
||||||
|
return global->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t pw_global_get_type(struct pw_global *global)
|
||||||
|
{
|
||||||
|
return global->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t pw_global_get_version(struct pw_global *global)
|
||||||
|
{
|
||||||
|
return global->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * pw_global_get_object(struct pw_global *global)
|
||||||
|
{
|
||||||
|
return global->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t pw_global_get_id(struct pw_global *global)
|
||||||
|
{
|
||||||
|
return global->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Bind to a global
|
||||||
|
*
|
||||||
|
* \param global the global to bind to
|
||||||
|
* \param client the client that binds
|
||||||
|
* \param version the version
|
||||||
|
* \param id the id
|
||||||
|
*
|
||||||
|
* Let \a client bind to \a global with the given version and id.
|
||||||
|
* After binding, the client and the global object will be able to
|
||||||
|
* exchange messages.
|
||||||
|
*
|
||||||
|
* \memberof pw_global
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pw_global_bind(struct pw_global *global, struct pw_client *client, uint32_t permissions,
|
||||||
|
uint32_t version, uint32_t id)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (global->bind == NULL)
|
||||||
|
goto no_bind;
|
||||||
|
|
||||||
|
if (global->version < version)
|
||||||
|
goto wrong_version;
|
||||||
|
|
||||||
|
res = global->bind(global, client, permissions, version, id);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
wrong_version:
|
||||||
|
res = SPA_RESULT_INCOMPATIBLE_VERSION;
|
||||||
|
pw_core_resource_error(client->core_resource,
|
||||||
|
client->core_resource->id,
|
||||||
|
res, "id %d: interface version %d < %d",
|
||||||
|
id, global->version, version);
|
||||||
|
return res;
|
||||||
|
no_bind:
|
||||||
|
res = SPA_RESULT_NOT_IMPLEMENTED;
|
||||||
|
pw_core_resource_error(client->core_resource,
|
||||||
|
client->core_resource->id,
|
||||||
|
res, "can't bind object id %d to interface", id);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Destroy a global
|
||||||
|
*
|
||||||
|
* \param global a global to destroy
|
||||||
|
*
|
||||||
|
* \memberof pw_global
|
||||||
|
*/
|
||||||
|
void pw_global_destroy(struct pw_global *global)
|
||||||
|
{
|
||||||
|
struct pw_core *core = global->core;
|
||||||
|
struct pw_resource *registry;
|
||||||
|
|
||||||
|
pw_log_debug("global %p: destroy %u", global, global->id);
|
||||||
|
|
||||||
|
spa_list_for_each(registry, &core->registry_resource_list, link) {
|
||||||
|
uint32_t permissions = pw_global_get_permissions(global, registry->client);
|
||||||
|
if (PW_PERM_IS_R(permissions))
|
||||||
|
pw_registry_resource_global_remove(registry, global->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_map_remove(&core->globals, global->id);
|
||||||
|
|
||||||
|
spa_list_remove(&global->link);
|
||||||
|
spa_hook_list_call(&core->listener_list, struct pw_core_events, global_removed, global);
|
||||||
|
|
||||||
|
pw_log_debug("global %p: free", global);
|
||||||
|
free(global);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue